cur*_*nii 2 c# unmanaged dllimport header-files
在 C 中,您可以编译一个静态库,该库依赖于定义多个函数的 C 头文件。您不需要知道哪个库最终将实现这些函数,因此您的静态库可以与实现无关。只要您提供有效的实现,您就可以将静态库链接到最终的可执行文件中。
我怎样才能在 C# 中做类似的事情?我想创建一个依赖于可由多个 C++ DLL 实现的通用 API 的库。(需要明确的是,我的意思是动态链接,而不是像上面的类比那样的静态链接。)但是要使用DllImportP/Invoke,我必须提供 DLL 名称。显然,我必须在某个时候这样做,但我想创建一个类库 DLL,它依赖于当时未指定的 DLL 中的 API,然后仅在最终版本中提供该非托管 DLL 的名称应用项目。
您提供的名称[DllImport]必须是编译时常量,因此您不能在此处传递“动态”值。但是,您可以使用一些默认名称甚至虚拟名称,然后使用NativeLibrary.SetDllImportResolver在运行时将此名称解析为有效库。
例如,在一个项目中我使用本机 Clibgphoto库。在 Windows 上,我将其包含到预编译的发行版中,因此我需要的功能被分为两个名为“libgphoto2-6.dll”和“libgphoto2_port-12.dll”的 dll。但是,在 Linux 和 Macos 上 - 您可以从包中安装此库,并且所有功能都将位于名为“gphoto”的库中。
然后我使用“windows”dll 名称定义导入:
private const string LibGPhotoName = "libgphoto2-6";
[DllImport(LibGPhotoName)]
public static extern int gp_widget_get_id(IntPtr widget, out int id);
Run Code Online (Sandbox Code Playgroud)
但如果我不在 Windows 上,我会这样做:
NativeLibrary.SetDllImportResolver(typeof(GPhoto2).Assembly, (name, asm, search) => {
if (name == "libgphoto2-6" || name == "libgphoto2_port-12")
{
return NativeLibrary.Load("gphoto2", asm, search);
}
return IntPtr.Zero;
});
Run Code Online (Sandbox Code Playgroud)
因此,如果运行时想要加载本机库“libgphoto2-6”或“libgphoto2_port-12” - 我告诉它加载“gphoto2”。
您也可以针对您的情况做同样的事情。
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |