非托管DLL的相对路径
可能重复:
在.NET中指定DllImport的搜索路径
我有一个非托管DLL。 对于清除,它是一个我想在我的C#代码中使用的C ++ dll。 问题是,它的Windows应用程序和用户可以安装在他们选择的任何目录。 所以我不能用静态路径来引用它,而且我也找不到一个给出相对路径的方法。 这是我尝试的代码:
[DllImport("mydll.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
public void SetDllDirectory(string lpPathName)
{
try
{
bool r = SetDllDirectory(lpPathName);
}
catch (Exception ex)
{
throw ex;
}
}
public void SetDirectoryPath()
{
try
{
DirectoryInfo directory = new DirectoryInfo(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath));
if (directory.Exists)
SetDllDirectory(directory.ToString() + "mydll.dll");
}
catch (Exception ex)
{
throw ex;
}
}
以下是我收到的错误。
无法在DLL“mydll.dll”中找到名为“SetDllDirectory”的入口点。
这个问题可能是一个复制品
“c#中的C ++非托管DLL”
“平台调用声明中DLL的相对路径”
对不起,但我没有在这些参考文献中找到任何解决方案。
此错误消息:
无法在DLL“mydll.dll”中找到名为“SetDllDirectory”的入口点。
没有提到无法找到DLL。 它说你的P / Invoke定义不正确。 在DLL( mydll.dll
)中没有名为SetDllDirectory
函数。 为什么要这样呢? 从DLL中导出的唯一函数是您明确编码和导出的函数。 由于您没有为SetDllDirectory
编写代码,并指出它应该从mydll.dll
导出,因此它不存在于DLL中。
除此之外,这个问题是无法回答的,除非你用真实的代码更新你的问题。 您至少需要发布您试图从非托管DLL调用的函数的签名,以及您在C#(托管)端尝试过的P / Invoke代码。
问题是,它的Windows应用程序和用户可以安装在他们选择的任何目录。 所以我不能用静态路径来引用它,而且我也找不到一个给出相对路径的方法。
这不是一个真正的问题。 相对路径工作得很好,它们的工作方式与您的问题表明您已经尝试过的方式完全相同。 您只需在P / Invoke定义中包含DLL的名称。 默认的DLL搜索顺序负责其他所有操作。 如果托管的EXE与您要P / Invoke的非托管DLL位于同一目录中,则所有内容都可以无缝工作。
用户选择安装应用程序的位置并不重要,只要DLL和EXE位于同一文件夹中即可。 这就是你的安装程序的工作。
只要你使用相对路径,你绝对不需要使用Win32 API中的SetDllDirectory
函数(它实际上是在kernel32.dll
定义的)。
如果您试图拼凑到非标准位置的非托管库中,则需要将此位置添加到Windows用于查找dll文件的dll搜索路径中。
如果您的用户可以告诉程序c / c ++库文件的位置,您可以在选择它时手动加载它。
public class UnsafeNativeMethods {
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetDllDirectory(string lpPathName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetDllDirectory(int bufsize, StringBuilder buf);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr LoadLibrary(string librayName);
[DllImport("mylibrary")]
public static extern void InitMyLibrary();
}
您可以使用某种形式的预加载程序调用上述程序,如下所示:
public void LoadDllFile( string dllfolder, string libname ) {
var currentpath = new StringBuilder(255);
UnsafeNativeMethods.GetDllDirectory( currentpath.Length, currentpath );
// use new path
UnsafeNativeMethods.SetDllDirectory( dllfolder );
UnsafeNativeMethods.LoadLibrary( libname );
// restore old path
UnsafeNativeMethods.SetDllDirectory( currentpath );
}
你可能会这样称呼它:
LoadDllFile( "c:whatever", "mylibrary.dll" );
链接地址: http://www.djcxy.com/p/44469.html