简体   繁体   English

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

[英]Calling C++ DLL from C++ and C#

I have a C++ application that I have to convert to a DLL. 我有一个C ++应用程序,我必须转换为DLL。 I have all the source. 我有所有的来源。

my function is extern "C" __declspec(dllexport) int mymain(int i, std::wstring myArgs) 我的函数是extern“C”__ declspec(dllexport)int mymain(int i,std :: wstring myArgs)

I need to be able to pass in the arguments from a c++ or c# wrapper. 我需要能够从c ++或c#包装器传入参数。 I am able to call this from a c++ console application without error. 我可以从c ++控制台应用程序中调用它而不会出错。 I am now trying to call it from C#. 我现在试图用C#调用它。

This is my c# code: 这是我的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);
    }
}

} }

When I run it I get 当我跑它时,我得到了

System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.' System.Runtime.InteropServices.SEHException:'外部组件引发了异常。'

I am out of ideas. 我没有想法。

TIA TIA

Specify Unicode but also, in your C or C++ function, use printf with "%S" (upper-case 'S' means wide-character string).. OR std::wcout . 指定Unicode,但在C或C ++函数中,使用带有“%S”的printf (大写“S”表示宽字符串)..或者std::wcout

Without that, it might print weird or terminate at the first null char it finds. 如果没有它,它可能会打印出奇怪或终止于它找到的第一个空字符。 Also, you might want to actually pass the length of the string, but that's entirely up to you. 此外,您可能希望实际传递字符串的长度,但这完全取决于您。

Note the signature of the C++ function uses LPCWSTR ( const wchar_t* ) for the myArgs parameter.. 请注意,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

Based on yr last comment u might need to: 基于您最后的评论,您可能需要:

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

anyway since I dont have rep.dll it's hard to guess 无论如何,因为我没有rep.dll,所以很难猜到

The naming used in your code: 您的代码中使用的命名:

 mymain(int iArgs, string aArgs); 

makes me think that what you are trying to do is probably passing an array of strings (similar to wmain(int argc, wchar_t** argv) ). 让我觉得你要做的就是传递一个字符串数组 (类似于wmain(int argc, wchar_t** argv) )。

If this is what you want, then on the native DLL side your function prototype would look like this: 如果这是你想要的,那么在本机DLL端你的函数原型将如下所示:

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

And on the C# side, you would write a PInvoke declaration like this: 在C#方面,你会写一个像这样的PInvoke声明:

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

that you can invoke in C# like this: 您可以像这样在C#中调用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM