如何从 C# 使用 C++ dll
How to use C++ dll from C#
我正在尝试在我的 C# 项目中包含 C++ 库 (DLL),但每次我这样做时,我都会在 VS2012 中收到以下错误消息
A reference to 'C:\Users\HiepDang\Desktop\mydll.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
当我尝试添加 Com+ 组件时,我在 window
中收到以下错误消息
One or more files do not contain components or type libraries. These files cannot be installed.
Error 80110425 occurred.
An unknown error occured. You should check all documentation for a solution. If no further information is available, please contract technical support
我正在关注话题 here and here,但我的问题没有解决。
在 C++ 中,我可以像这样使用 dll:
//Header
extern "C" __declspec( dllimport ) int mymethod(const char *key, char *data, size_t buflen);
//Code test
const char* key = "test";
char* data = new char[1024];
int buflen = 1024;
int result = mymethod(key,data, buflen);
在 C# 中,我将 dll 用作:
//define dll
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, [MarshalAs(UnmanagedType.LPTStr)]string data, uint buflen);
//method test
private static int testdll()
{
string key = "123456789";
string buf = string.Empty;
mymethod(key, buf, 1024);
return 0;
}
你能告诉我解决它的方法吗?
P.s: 我的英语不好。如有不便之处请见谅
编辑:我在dll的方法中解释变量。 “key”作为字符串输入有8-13个字符,mymethod将被加密生成“buf”。我需要“buf”变量。
在 C# 中你必须使用 StringBuilder()
//define dll
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int mymethod(string key, StringBuilder data, IntPtr buflen);
//method test
private static int testdll()
{
string key = "123456789";
StringBuilder buf = new StringBuilder(1024);
mymethod(key, buf, (IntPtr)buf.Capacity);
string buf2 = buf.ToString()
return 0;
}
请注意 size_t
的大小为 IntPtr
,因为它在 x86 上为 4 个字节,在 x64 上为 8 个字节。
在你的cpp项目中,
变化
extern "C" __declspec( dllimport )
到
extern "C" __declspec( dllexport )
并将生成的cpp dll文件"mydll.dll"复制到你的C#项目的outdir中。
顺便说一句,如果第二个参数不是字符串而是原始二进制数据,你最好使用 byte[] 而不是 char*。
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, byte[] data, uint buflen);
字节数组自动编组。
像下面这样使用它。
var key = "A key";
var data = new byte[10];
//fill data
mymethod(key, data, (uint)data.Length);
也因为我的 DLL 是非托管的(意味着它是一种非托管语言,如 C 或 C++)然后根据 DllImport 的规范,"Indicates that the attributed method is exposed by a unmanaged DLL as a static entry point"。为什么我不能使用这个"DllImport"?
如果它是一个 c++ com 对象,如果你用 regsvr32 注册它,你可以在 visual studio com 引用选项卡中添加对 dll 的引用,通常 visual studio 创建一个 dll(我认为它称为运行时可调用包装器)它你可以看到是用 nameoflibrary.interop.dll 创建的。所以 MyExecRefsDll.dll 如果是一个 com 对象就会变成 MyExexRefs.Interop.dll。但是,当您添加引用时,visual studio 通常会在托管代码中自动为您执行此操作。如果您通过在 c++ 中使用 atl 模板将 c++ dll 创建为 com 对象,则更容易从 dotnet 访问(我从引用另一个 dll 文件的 dll 引用非托管 c++ 代码(没有从第二个 dll 复制的代码我只是引用 tlb 、lib、dll 文件和 visual studio 完成其他所有工作。
我正在尝试在我的 C# 项目中包含 C++ 库 (DLL),但每次我这样做时,我都会在 VS2012 中收到以下错误消息
A reference to 'C:\Users\HiepDang\Desktop\mydll.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
当我尝试添加 Com+ 组件时,我在 window
中收到以下错误消息One or more files do not contain components or type libraries. These files cannot be installed.
Error 80110425 occurred.
An unknown error occured. You should check all documentation for a solution. If no further information is available, please contract technical support
我正在关注话题 here and here,但我的问题没有解决。
在 C++ 中,我可以像这样使用 dll:
//Header
extern "C" __declspec( dllimport ) int mymethod(const char *key, char *data, size_t buflen);
//Code test
const char* key = "test";
char* data = new char[1024];
int buflen = 1024;
int result = mymethod(key,data, buflen);
在 C# 中,我将 dll 用作:
//define dll
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, [MarshalAs(UnmanagedType.LPTStr)]string data, uint buflen);
//method test
private static int testdll()
{
string key = "123456789";
string buf = string.Empty;
mymethod(key, buf, 1024);
return 0;
}
你能告诉我解决它的方法吗?
P.s: 我的英语不好。如有不便之处请见谅
编辑:我在dll的方法中解释变量。 “key”作为字符串输入有8-13个字符,mymethod将被加密生成“buf”。我需要“buf”变量。
在 C# 中你必须使用 StringBuilder()
//define dll
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int mymethod(string key, StringBuilder data, IntPtr buflen);
//method test
private static int testdll()
{
string key = "123456789";
StringBuilder buf = new StringBuilder(1024);
mymethod(key, buf, (IntPtr)buf.Capacity);
string buf2 = buf.ToString()
return 0;
}
请注意 size_t
的大小为 IntPtr
,因为它在 x86 上为 4 个字节,在 x64 上为 8 个字节。
在你的cpp项目中, 变化
extern "C" __declspec( dllimport )
到
extern "C" __declspec( dllexport )
并将生成的cpp dll文件"mydll.dll"复制到你的C#项目的outdir中。
顺便说一句,如果第二个参数不是字符串而是原始二进制数据,你最好使用 byte[] 而不是 char*。
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, byte[] data, uint buflen);
字节数组自动编组。
像下面这样使用它。
var key = "A key";
var data = new byte[10];
//fill data
mymethod(key, data, (uint)data.Length);
也因为我的 DLL 是非托管的(意味着它是一种非托管语言,如 C 或 C++)然后根据 DllImport 的规范,"Indicates that the attributed method is exposed by a unmanaged DLL as a static entry point"。为什么我不能使用这个"DllImport"? 如果它是一个 c++ com 对象,如果你用 regsvr32 注册它,你可以在 visual studio com 引用选项卡中添加对 dll 的引用,通常 visual studio 创建一个 dll(我认为它称为运行时可调用包装器)它你可以看到是用 nameoflibrary.interop.dll 创建的。所以 MyExecRefsDll.dll 如果是一个 com 对象就会变成 MyExexRefs.Interop.dll。但是,当您添加引用时,visual studio 通常会在托管代码中自动为您执行此操作。如果您通过在 c++ 中使用 atl 模板将 c++ dll 创建为 com 对象,则更容易从 dotnet 访问(我从引用另一个 dll 文件的 dll 引用非托管 c++ 代码(没有从第二个 dll 复制的代码我只是引用 tlb 、lib、dll 文件和 visual studio 完成其他所有工作。