简体   繁体   中英

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

I have a C++ application that I have to convert to a DLL. I have all the source.

my function is 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. I am able to call this from a c++ console application without error. I am now trying to call it from C#.

This is my c# code:

    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.'

I am out of ideas.

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 .

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..

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

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) ).

If this is what you want, then on the native DLL side your function prototype would look like this:

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

And on the C# side, you would write a PInvoke declaration like this:

[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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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