如何从c#中使用c++ dll

本文关键字:c++ dll | 更新日期: 2023-09-27 17:49:59

我试图包括c++库(DLL)在我的c#项目,但每次我这样做,我得到以下错误消息在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+组件时,我在窗口

中得到以下错误消息

一个或多个文件不包含组件或类型库。这些文件无法安装。

发生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。我的英语不好。如有不便之处,我很抱歉

编辑:我在dll中解释了方法中的变量。"key"由于字符串输入有8-13个字符,mymethod将被加密生成&;buf&;。我需要变量"buf"

如何从c#中使用c++ dll

在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字节。

还因为我的DLL是非托管的(意味着它是一种非托管语言,如C或c++),然后根据DllImport的规范,"指示属性方法由非托管DLL作为静态入口点公开"。为什么我不能使用这个"DllImport"?如果它是一个c++ com对象,如果你用regsvr32注册它,你可以在visual studio com引用选项卡中添加对dll的引用,通常visual studio会创建一个dll(我认为它被称为运行时可调用的包装器),你可以看到它是以library.interop.dll的名称创建的。所以myexexref .dll如果是一个com对象就会变成myexexref . interop .dll。但是当您添加参考时,visual studio通常会在托管代码中自动为您完成此操作。如果您通过在c++中使用atl模板创建一个c++ dll作为com对象,则更容易从dotnet访问(我从引用另一个dll文件的dll中引用非托管c++代码)(没有从第二个dll复制的代码,我只是引用了tlb, lib, dll文件,visual studio做其他一切。

在你的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);

字节数组被自动封送。

MSDN参考

像下面这样使用

var key = "A key";
var data = new byte[10];
//fill data
mymethod(key, data, (uint)data.Length);