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

从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

+1

的std :: wstring的是一个C++类的......你不能指望一个C#字符串被转换成“自动地”。 – yms

+0

请阅读此处: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

+0

我实现了你的建议并单独离开C#调用,但期望在C++ dll中使用LPTSTR作为参数。我可以调用它,但我在dll中获得的数据是垃圾 myArgsPtr = 0x000000f3cabfec80 L“倯瑡㩣瑜浥屰狯⁴⁴䈯捡画印捥牵⁹莹狯⹲⹲p” – Jeff

指定的Unicode,而且,在C

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

反正或C++函数,使用printf和“%S”(大写字母'S'表示宽字符字符串)..或std::wcout

没有它,它可能会打印奇怪或终止在它找到的第一个空字符。另外,您可能希望实际传递字符串的长度,但这完全取决于您。

注意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 

基于去年年ü评论可能需要:因为我没有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);