Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用非静态路径从DLL调用函数_C#_.net_Dll_Interop_Runtime - Fatal编程技术网

C# 使用非静态路径从DLL调用函数

C# 使用非静态路径从DLL调用函数,c#,.net,dll,interop,runtime,C#,.net,Dll,Interop,Runtime,我有一个DLL,我需要从中访问方法 在大多数情况下,我只是使用[DllImport]从非托管程序集访问方法,但在这种情况下,问题是它需要在实例化时指向DLL的路径,因此需要一个常量字符串 这个特定的DLL是与我的应用程序一起安装的,我不能保证程序安装后它会在哪里(我不希望将它放在像%SystemRoot%这样的静态位置) 那么,在C#中是否有一种方法可以在运行时通过变量路径从DLL声明和使用方法 如有任何意见或建议,将不胜感激 根本不要使用路径。当尝试从DLL动态或静态加载函数时,Windows

我有一个DLL,我需要从中访问方法

在大多数情况下,我只是使用[DllImport]从非托管程序集访问方法,但在这种情况下,问题是它需要在实例化时指向DLL的路径,因此需要一个常量字符串

这个特定的DLL是与我的应用程序一起安装的,我不能保证程序安装后它会在哪里(我不希望将它放在像%SystemRoot%这样的静态位置)

那么,在C#中是否有一种方法可以在运行时通过变量路径从DLL声明和使用方法


如有任何意见或建议,将不胜感激

根本不要使用路径。当尝试从DLL动态或静态加载函数时,Windows使用默认方法搜索DLL


确切的搜索逻辑记录在文档的MSDN中-基本上,如果DLL仅由您的应用程序使用,请在安装过程中将其放入应用程序所在的文件夹中,不要担心。如果它是一个常用的DLL,请将它放在LoadLibrary()搜索的文件夹结构中的某个位置,然后就会找到它。

完全不要使用路径。当尝试从DLL动态或静态加载函数时,Windows使用默认方法搜索DLL


确切的搜索逻辑记录在文档的MSDN中-基本上,如果DLL仅由您的应用程序使用,请在安装过程中将其放入应用程序所在的文件夹中,不要担心。如果它是一个常用的DLL,请将它放在LoadLibrary()搜索的文件夹结构中的某个位置,然后就会找到它。

这有点不对劲,但是既然您说可以在运行时找到DLL的路径,为什么不在使用任何函数之前将其复制到当前的工作目录中呢?这样,dll将存在于exe旁边,并由LoadLibrary找到。DllImport中不需要任何其他路径

从动态路径使用方法的唯一其他方法是这样做:
1) 对&
2) 从所需路径加载库(LoadLibrary)
3) 找到所需的函数(GetProcAddress)
4) 将指针投射到代理
5) 调用它。


当然,您需要为每个要以这种方式“导入”的函数声明一个委托,因为您必须将指针强制转换为委托。

这是一个小技巧,但是既然您说您可以在运行时找到dll的路径,为什么不在使用任何函数之前将其复制到当前的工作目录中呢?这样,dll将存在于exe旁边,并由LoadLibrary找到。DllImport中不需要任何其他路径

从动态路径使用方法的唯一其他方法是这样做:
1) 对&
2) 从所需路径加载库(LoadLibrary)
3) 找到所需的函数(GetProcAddress)
4) 将指针投射到代理
5) 调用它。


当然,您需要为每个要以这种方式“导入”的函数声明一个委托,因为您必须将指针强制转换为委托。

我也遇到过类似的情况。我使用机器上安装的SDK中的DLL。我从SDKs注册表项获取DLL的目录位置。我在executing users PATH变量上设置了DLL位置(仅临时修改)。基本上,它允许您为要调用的DLL设置动态路径,因此它不必来自注册表。请注意,路径变量是Windows查找DLL的最后一个位置。但另一方面,它不会改变Windows查找DLL的其他位置

例如:

要在DLL上调用的API:

[DllImport("My.DLL")]
private static extern IntPtr ApiCall(int param);
获取注册表项(需要使用Microsoft.Win32;):

在路径变量上添加DLL的路径(在Linq中找到Concat()):

void UpdatePath(IEnumerable路径){
var path=new[]{Environment.GetEnvironmentVariable(“path”)??“};
path=path.Concat(路径);
string modified=string.Join(Path.PathSeparator.ToString(),Path);
setEnvironment变量(“路径”,已修改);
}
开始使用API调用:

var sdkPathToAdd = GetRegistryKeyPath();
IList<string> paths = new List<string>
        {
            Path.Combine(sdkPathToAdd),
            Path.Combine("c:\anotherPath")
        };
UpdatePath(paths);

//Start using
ApiCall(int numberOfEyes);
var sdkPathToAdd=GetRegistryKeyPath();
IList路径=新列表
{
路径合并(sdkPathToAdd),
Path.Combine(“c:\anotherPath”)
};
更新路径(路径);
//开始使用
ApiCall(int numberOfEyes);

我也遇到过类似的情况。我使用机器上安装的SDK中的DLL。我从SDKs注册表项获取DLL的目录位置。我在executing users PATH变量上设置了DLL位置(仅临时修改)。基本上,它允许您为要调用的DLL设置动态路径,因此它不必来自注册表。请注意,路径变量是Windows查找DLL的最后一个位置。但另一方面,它不会改变Windows查找DLL的其他位置

例如:

要在DLL上调用的API:

[DllImport("My.DLL")]
private static extern IntPtr ApiCall(int param);
获取注册表项(需要使用Microsoft.Win32;):

在路径变量上添加DLL的路径(在Linq中找到Concat()):

void UpdatePath(IEnumerable路径){
var path=new[]{Environment.GetEnvironmentVariable(“path”)??“};
path=path.Concat(路径);
string modified=string.Join(Path.PathSeparator.ToString(),Path);
setEnvironment变量(“路径”,已修改);
}
开始使用API调用:

var sdkPathToAdd = GetRegistryKeyPath();
IList<string> paths = new List<string>
        {
            Path.Combine(sdkPathToAdd),
            Path.Combine("c:\anotherPath")
        };
UpdatePath(paths);

//Start using
ApiCall(int numberOfEyes);
var sdkPathToAdd=GetRegistryKeyPath();
IList路径=新列表
{
路径合并(sdkPathToAdd),
Path.Combine(“c:\anotherPath”)
};
更新路径(路径);
//开始使用
ApiCall(int numberOfEyes);

在此特定实例中,我无法将DLL与我的应用程序放在同一目录中,它位于我的应用程序的子目录中,我正试图使用相对路径来声明它。这在某些机器上有效,但不一致=\尝试导入SetDllDirect