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

Calling C++ DLL from C++ and C#

我有一个 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: 'External component has thrown an exception.'

我没主意了。

TIA

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

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

反正我没有rep.dll很难猜

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

否则,它可能会打印奇怪或在它找到的第一个空字符处终止。此外,您可能想要实际传递字符串的长度,但这完全取决于您。

注意 C++ 函数的签名使用 LPCWSTR (const 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

您的代码中使用的命名:

mymain(int iArgs, string aArgs);

让我觉得你想做的可能是传递一个 array 字符串(类似于 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);