2023年9月29日 修正
業務内容漏洩リスクを指摘されたため、質問の内容を伏せさせていただきます。
協力していただいた方々、大変申し訳ありません。
動作はできたもののまだテストはしていない状況です。
テストが通り世に出回りましたら、ブログなど何らかの方法で公開させていただきます。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
今だと、NativeAOT+UnmanagedCallersOnlyAttributeで作成する方法もあるようです。
投稿2023/09/28 01:43
総合スコア136
0
DLLExport を使ったクラスのサンプルです。
SendMailInternal にメール送信処理を書いてください。
SmtpClient ではなく、MailKit を使いましょう。
csharp
1using System; 2using System.Text; 3using System.Runtime.InteropServices; 4 5namespace smtpmail 6{ 7 public class SendMailCaller 8 { 9 // VB の宣言 10 //Private Declare Function SendMail Lib "smtpmail" _ 11 // (sServer As String, sTo As String, sFrom As String, _ 12 // sSubject As String, sBody As String, sFile As String) As String 13 14 [DllExport(CallingConvention.StdCall)] 15 public static IntPtr SendMail( 16 ref IntPtr iServer, ref IntPtr iTo, ref IntPtr iFrom, 17 ref IntPtr iSubject, ref IntPtr iBody, ref IntPtr iFile) { 18 19 string sServer = GetByRefString(iServer); 20 string sTo = GetByRefString(iTo); 21 string sFrom = GetByRefString(iFrom); 22 string sSubject = GetByRefString(iSubject); 23 string sBody = GetByRefString(iBody); 24 string sFile = GetByRefString(iFile); 25 26 string result = SendMailInternal( 27 sServer, sTo, sFrom, 28 sSubject, sBody, sFile); 29 30 return ResultString(result); 31 } 32 33 private static string GetByRefString(IntPtr ptr) { 34 if (ptr == IntPtr.Zero) { 35 return string.Empty; 36 } 37 return Marshal.PtrToStringAnsi(ptr); 38 } 39 40 private static IntPtr ResultString(string value) { 41 if (string.IsNullOrEmpty(value)) { 42 return IntPtr.Zero; 43 } 44 var enc = Encoding.GetEncoding("SHIFT_JIS"); 45 var bytes = enc.GetBytes(value); 46 return SysAllocStringByteLen(bytes, bytes.Length); 47 } 48 49 [DllImport("oleaut32.dll", CharSet = CharSet.Ansi)] 50 private static extern IntPtr SysAllocStringByteLen( 51 byte[] bytes, int len); 52 53 private static string SendMailInternal( 54 string sServer, string sTo, string sFrom, 55 string sSubject, string sBody, string sFile) { 56 57 Console.WriteLine($"sServer={sServer.Length}{sServer}"); 58 Console.WriteLine($"sTo={sTo.Length}{sTo}"); 59 Console.WriteLine($"sFrom={sFrom.Length}{sFrom}"); 60 Console.WriteLine($"sSubject={sSubject.Length}{sSubject}"); 61 Console.WriteLine($"sBody={sBody.Length}{sBody}"); 62 Console.WriteLine($"sFile={sFile.Length}{sFile}"); 63 64 // ここにメール送信処理を書いてください。 65 66 return "SendMail Success!"; 67 } 68 69 } 70} 71
投稿2023/09/22 04:02
総合スコア2696
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/09/22 07:44
退会済みユーザー
2023/09/22 09:14
0
ベストアンサー
C# で VB6 から呼び出せる dll を作るなら、 COM を作ってください。
まずは本家。
「COM クラスの例」
https://learn.microsoft.com/ja-jp/dotnet/csharp/advanced-topics/interop/example-com-class
あとは、VBA 用に作った先人がいらっしゃいますので、「VBA C# COM」でネット検索するとでてくるでしょう。
どこかの偉い人がレガシー dll として作る方法を提供していますが、裏技なのでお勧めしません。
おすすめのページです。
「C# で COM オブジェクトを作ってみる」
https://qiita.com/tomochan154/items/1ce33f2aef167c0fed9d
AnyCPU でビルドすると、32bit/64bit 双方で動く dll になるようです。
VB6 なので、32bit だけで良いのですが、ここで注意事項。
Visual Studio 2019 までは 32bit だったので、ビルドすると 32bit の COM として登録されますが、2020 は 64bit なので 64bit の COM として登録されるので手動で登録する必要があります。
追記:VB6側は変更できないというのを見落としていたので
前述したとおり、C# は基本的にレガシー DLL を作成できません。
なので、C# の DLL を呼び出したいのであれば、C++/CLR でラッパー DLL を作ることになるでしょう。
VB6 → C++/CLR → C# という感じで呼び出すわけですね。
VB の宣言が
vb
1Private Declare Function SendMail Lib "smtpmail" _ 2 (sServer As String, sTo As String, sFrom As String, _ 3 sSubject As String, sBody As String, sFile As String) As String
のようになっているので C++/CLR 側は
c++
1extern "C" { 2 __declspec(dllexport) BSTR WINAPI SendMail( 3 BSTR* sServer, BSTR* sTo, BSTR* sFrom, 4 BSTR* sSubject, BSTR* sBody, BSTR* sFile) { 5 char buf[] = "this is a pen"; 6 return SysAllocStringByteLen(buf, lstrlenA(buf)); 7 } 8}
という感じになるかと思います。
文字列は BSTR で渡されますが、困ったことに VB 側が Unicode から Ansi に変換してしまいます。
ですから、Ansi → Unicode の変換を行ってから C# の DLL を呼び出す必要があります。
逆に C# から渡された文字列は、Unicode から Ansi への変換を行ってから VB6 に戻す必要があります。
投稿2023/09/21 04:30
編集2023/09/22 08:03総合スコア2696
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2023/09/21 05:16
2023/09/21 05:28
2023/09/21 05:30
退会済みユーザー
2023/09/21 07:13
退会済みユーザー
2023/09/21 08:10
2023/09/21 09:06 編集
2023/09/21 10:03 編集
退会済みユーザー
2023/09/22 00:53
退会済みユーザー
2023/09/22 02:04
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/09/28 03:30
退会済みユーザー
2023/09/28 04:41