如何使用C#中的C ++ dll

时间:2015-05-20 04:08:11

标签: c# c++ .net dll

我尝试在我的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发生。

     

发生未知错误。您应该检查解决方案的所有文档。如果没有进一步的信息,请与技术支持部门签订合同

我跟随线程herehere,但我的问题没有解决。

在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"。

3 个答案:

答案 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);

字节数组自动编组。

Reference on MSDN

如下所示使用它。

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完成其他所有工作。