从C ++和C#调用C ++ DLL

时间:2017-10-18 23:06:59

标签: c# c++ interop pinvoke

我有一个C ++应用程序,我必须转换为DLL。我有所有来源。

我的功能是 外部“C” __declspec(dllexport)int mymain(int i,std :: wstring myArgs)

我需要能够从c ++或c#包装器传入参数。我可以从c ++控制台应用程序中调用它而不会出错。我现在试图用C#来调用它。

这是我的c#代码:

    public static class DllHelper
{

    [DllImport("rep.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int mymain(int iArgs, string aArgs);
}

class Program
{



    static void Main(string[] args)
    {
        string s = "my string data";
        DllHelper.mymain(0, s);
    }
}

}

当我运行它时,我得到了

  

System.Runtime.InteropServices.SEHException:'外部组件引发了异常。'

我没有想法。

TIA

3 个答案:

答案 0 :(得分:2)

指定Unicode,但在C或C ++函数中,使用printf和"%S" (大写' S'表示宽字符串)..或std::wcout

如果没有它,它可能会打印出奇怪或终止于它找到的第一个空字符。此外,您可能希望实际传递字符串的长度,但这完全取决于您。

请注意,C ++函数的签名使用LPCWSTRconst wchar_t*)作为myArgs参数。

public static class DllHelper
{

    [DllImport("rep.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
    public static extern int mymain(int iArgs, string aArgs);
}

class Program
{
    static void Main(string[] args)
    {
        string s = "my string data";
        DllHelper.mymain(0, s);
    }
}

#ifdef __cplusplus
extern "C" {
#endif

int __declspec(dllexport) mymain(int i, const wchar_t* myArgs)
{
    #ifdef __cplusplus
    std::wcout<<std::wstring(myArgs)<<L"\n";
    #else
    printf(L"%S\n", myArgs);
    #endif
}

#ifdef __cplusplus
}
#endif

答案 1 :(得分:1)

根据您最后的评论,您可能需要:

[DllImport("rep.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]

无论如何,因为我没有rep.dll,所以很难猜到

答案 2 :(得分:1)

代码中使用的命名:

mymain(int iArgs, string aArgs);

让我觉得你要做的就是传递一个数组字符串(类似于wmain(int argc, wchar_t** argv))。

如果这是您想要的,那么在本机DLL端,您的函数原型将如下所示:

extern "C" int __declspec(dllexport) mymain(int iArgs, wchar_t** aArgs)

在C#方面,你会写一个像这样的PInvoke声明:

[DllImport("rep.dll", 
    CallingConvention=CallingConvention.Cdecl, 
    CharSet=CharSet.Unicode)]
public static extern int mymain(int iArgs, [In] string[] aArgs);

你可以像这样用C#调用:

string[] test = { "C64", "Bravo", "Charlie" };
int returnCode = mymain(test.Length, test);