在寻找已经针对我的类似问题提出的解决方案后, 因为这是我第一次在.NET应用程序中使用非.NET DLL, 我真的需要你的帮助。
我有一个使用MVVM模式的WPF应用程序,在我的ViewModel
类中,我需要使用在C ++中完成的DLL来恢复令牌。我在C ++中有一个使用这个DLL的例子,所以我有方法的名字,但我不能在C#中做同样的事情。我知道我必须使用DllImport
来使用这个方法,但是如何实现它并在C#中使用指针?
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
int main()
{
HINSTANCE hinst = NULL;
typedef bool ( *GetTokenProto )( char ** );
typedef void ( *FreeTokenProto )( char * );
GetTokenProto GetToken;
FreeTokenProto FreeToken;
std::string str = "DllName.dll";
std::string token;
if ( (hinst = LoadLibraryA(str.c_str()) ) )
{
GetToken = (GetTokenProto) GetProcAddress(hinst, "GetToken");
FreeToken = (FreeTokenProto) GetProcAddress(hinst, "FreeToken");
if (GetToken && FreeToken)
{
char *buf;
if (GetToken(&buf))
{
token = buf;
FreeToken(buf);
std::cout << "Token:" << token << std::endl;
}
else
{
std::cerr << "DLL loaded but no token" << std::endl;
exit(1);
}
}
else
{
std::cerr << "DLL loaded but missing proc address(es)" << std::endl;
exit(1);
}
FreeLibrary(hinst);
}
else
{
std::cerr << "Failed to load DLL" << std::endl;
exit(1);
}
return 0;
}
更新
[DllImport("DllName.dll", EntryPoint = "GetToken", CallingConvention = CallingConvention.Cdecl)]
public static extern bool get_token(ref string token);
[DllImport("DllName.dll", EntryPoint = "FreeToken", CallingConvention = CallingConvention.Cdecl)]
public static extern void free_token(ref string token);
public static string a_token;
public string get_token_method()
{
try
{
string buffer = null;
if (get_token(ref buffer))
{
a_token = buffer;
free_token(ref buffer);
Debug.WriteLine("token : " + a_refresh_token);
}
else
{
Debug.WriteLine("DLL Loaded but no token");
}
}
catch (Exception ex)
{
Debug.WriteLine("\n" + ex.Message);
}
return a_refresh_token;
}
错误
我有一个例外&#34; System.DllNotFoundException&#34; :无法加载DLL &#39; DllName.dll&#39;:找不到指定的模块。 (例外 来自HRESULT:0x8007007E)。
Dll文件位于.exe(.. \ bin \ Debug)
的同一文件夹中答案 0 :(得分:1)
如果您的DLL位于同一目录中,则仍有一些问题可能存在。
首先
Dll可能有依赖
您使用的本机DLL可能还有其他依赖项 已安装(try Dependency Walker)。如果本机DLL需要 示例注册表设置,配置文件等。这些也应该是 当下。它应该以与您相同的方式分发给用户计算机 将它安装在开发机器上。
很可能你错过了C ++可再发行组件包(我不是哪一个),Dependency Walker
应该告诉你什么
<强>其次强>
它可能针对不同的位数,即x86 x64,所以id尝试更改项目以查看是否有帮助
右键单击您的项目,然后选择属性。
在属性中,选择构建选项卡。在平台目标下,选择x86。
按Ctrl + Shift + S保存所有文件,右键单击解决方案并选择“清除”以清除旧的二进制文件。之后的任何构建 应该是32位
答案 1 :(得分:0)
您可以在调用dll之前使用SetDllDirectory方法设置dll的路径
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetDllDirectory(string lpPathName);
答案 2 :(得分:0)
如果你想从c ++中获取字符串,你还应该在c#端使用StringBuilder而不是string。