从 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);
我有一个 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);