C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 140 を表示中)
■82374 / )  Re[6]: VBでC++のDLLを呼び出す方法
□投稿者/ 魔界の仮面弁士 (1036回)-(2017/01/05(Thu) 20:19:48)
No82371 (ぎゅんぎゅ さん) に返信
> パス名を指定して別のフォルダーに入れるにはどうしたら良いですか?

「Declare ステートメントの Lib 句」または
「DllImport 属性の最初の引数(dllName)」に
フルパスを指定してみてください。

もしくは、フルパスではなくファイル名だけで指定し、
初回呼び出しの直前に Directory.SetCurrentDirectory する手もあります。
ファイル名のみで指定した場合の探索順序は、下記を参考にしてみて下さい。
https://msdn.microsoft.com/ja-jp/library/7d83bc18.aspx


それ以外だと、LoadLibrary / GetProcAddress / FreeLibrary とか。



> VBやC#で出力したDLLファイルは
EXE 内に含めてしまうと、もはや "Dynamic" Link Library では無いですね。


> VBでEXEファイル内に含めることができますが。
ILMerge のことでしょうか?


> C++で出力したDLLファイルを含めることはできないのでしょうか?
PE ローダーをエミュレートして、エントリポイントを
Marshal.GetDelegateForFunctionPointer してみるとか。
https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/


とりあえず、_stdcall 規約の DLL であれば、こんな感じで呼び出せました。


Imports System.ComponentModel
Imports System.IO
Imports System.Runtime.InteropServices
Imports Microsoft.WinAny.Interop

Module Module1
 ' エントリポイント用のデリゲートを用意しておきます。
 ' 今回は ANSI パスを受け取る DLL だったので、LPStr を指定していますが、もしも
 ' ANSI / Unicode の切替を動的に行う必要があれば、ByVal pFile As IntPtr にしておいて
 ' Marshal.StringToHGlobal何某 を併用してみてください。
 Private Delegate Function getFileCRC32Delegate(<MarshalAs(UnmanagedType.LPStr), [In]> ByVal file As String) As UInteger

 Sub Main(ByVal args() As String)
  ' アンマネージ DLL のバイナリをリソースに埋め込んでおくか、
  ' あるいは CRC32.DLL の CRC32Table のようにハードコーディングしておきます。
  Dim bin() As Byte = My.Resources.PortableExecutable

  ' バイナリから DynamicNativeLibrary を生成します。
  ' https://code.msdn.microsoft.com/vstudio/How-to-use-MicrosoftWinAnyH-5c5bf341/sourcecode?fileId=95371&pathId=305420959
  Using dll As New DynamicNativeLibrary(bin)

   ' エントリポイントを指定してデリゲート インスタンスを取得します。
   Dim getFileCRC32 = DirectCast(dll.GetDelegateForFunction("getFileCRC32", GetType(getFileCRC32Delegate)), getFileCRC32Delegate)
   If getFileCRC32 Is Nothing Then
    Const ERROR_MOD_NOT_FOUND As Integer = 126
    Throw New Win32Exception(ERROR_MOD_NOT_FOUND)
   End If

   ' コマンドラインで渡されたファイルの CRC32 を出力します。
   For Each sPath As String In args
    Console.WriteLine(sPath)
    If Not File.Exists(sPath) Then
     Console.Error.WriteLine("ファイルが見つかりません。")
    Else
     Dim crc32 As UInteger = getFileCRC32(sPath)
     Console.Out.WriteLine(crc32.ToString("X8"))
    End If
   Next
  End Using

  Console.Write("Hit Any Key...")
  Console.ReadKey()
 End Sub
End Module
返信 編集キー/


管理者用

- Child Tree -