我尝试在我的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 + Component时,我在窗口中收到以下错误消息
一个或多个文件不包含组件或类型库。无法安装这些文件。
错误80110425发生。
发生未知错误。您应该检查解决方案的所有文档。如果没有进一步的信息,请与技术支持部门签订合同
在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中解释方法中的变量。 "键"由于字符串输入有8-13个字符,mymethod将被加密以生成" buf"。我需要变量" buf"。
答案 0 :(得分:2)
在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个字节。
答案 1 :(得分:1)
在你的cpp项目中, 变化
extern "C" __declspec( dllimport )
到
extern "C" __declspec( dllexport )
复制生成的cpp dll文件" mydll.dll"到你的C#项目的外围。
顺便说一句,如果第二个参数数据不是字符串而是原始二进制数据,那么你最好使用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);
答案 2 :(得分:0)
另外因为我的DLL是不受管理的(意思是它是一种非托管语言,如C或C ++),那么根据DllImport的规范,"表示属性方法由非托管DLL作为静态入口点公开&# 34 ;.为什么我不能使用这个" DllImport"? 如果你用regsvr32注册它是c ++ com对象,你可以在visual studio com references选项卡中添加对dll的引用,通常visual studio会创建一个dll(我认为它叫做运行时可调用包装器),你可以看到它是用nameoflibrary.interop.dll。所以MyExecRefsDll.dll如果是一个com对象将成为MyExexRefs.Interop.dll。但是当您添加引用时,Visual Studio通常会在托管代码中自动为您执行此操作。如果你通过在c ++中使用atl模板创建一个c ++ dll作为com对象,则更容易从dotnet访问(Iam引用来自dll的非托管c ++代码引用另一个dll文件(没有代码从第二个dll复制我只是引用tlb ,lib,dll文件和visual studio完成其他所有工作。