从C++和C调用C++ DLL
问题描述:
我有一个C++应用程序,我必须将其转换为DLL。我有所有的来源。从C++和C调用C++ DLL
我的职责是 的extern “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:“外部组件引发的异常。 “
我不知道。
TIA
答
指定的Unicode,而且,在C
[DllImport("rep.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
反正或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
答
基于去年年ü评论可能需要:因为我没有rep.dll很难猜测
答
在你的代码中使用的命名:
mymain(int iArgs, string aArgs);
让我想到你试图做的事情可能是传递一个数组字符串(类似到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);
的std :: wstring的是一个C++类的......你不能指望一个C#字符串被转换成“自动地”。 – yms
请阅读此处:https://social.msdn.microsoft.com/Forums/en-US/fec28110-7a53-4fb5-8db6-3463aee768e1/marshalling-a-string-by-reference-from-c-to-unmanaged- c-and-back?forum = clr – yms
我实现了你的建议并单独离开C#调用,但期望在C++ dll中使用LPTSTR作为参数。我可以调用它,但我在dll中获得的数据是垃圾 myArgsPtr = 0x000000f3cabfec80 L“倯瑡㩣瑜浥屰狯⁴⁴䈯捡画印捥牵⁹莹狯p” – Jeff