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.