我的C#模块必须与C ++ dll进行通信,该C ++ dll公开了一组函数,并且需要根据被调用函数返回的数据进行处理。
这里是我的C#代码,其中调用了C ++函数(Npr),
[DllImport("CppModule.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Npr"), System.Security.SuppressUnmanagedCodeSecurity]
public static extern IntPtr Npr([MarshalAs(UnmanagedType.LPWStr)]string moduleIDCur,
[MarshalAs(UnmanagedType.LPWStr)]string mName,
[MarshalAs(UnmanagedType.LPWStr)]string threadID,
[MarshalAs(UnmanagedType.LPWStr)]string sessionID,
[MarshalAs(UnmanagedType.LPWStr)]string reqID,
[MarshalAs(UnmanagedType.LPWStr)]string siteID,
[MarshalAs(UnmanagedType.LPWStr)]string siteName,
[MarshalAs(UnmanagedType.LPWStr)]string nodeOrder,
[MarshalAs(UnmanagedType.LPWStr)]string dateTime,
[MarshalAs(UnmanagedType.LPWStr)]string rType,
[MarshalAs(UnmanagedType.LPWStr)]string rCode,
[MarshalAs(UnmanagedType.LPWStr)]string headStr,
[MarshalAs(UnmanagedType.LPWStr)]string cookStr,
[MarshalAs(UnmanagedType.LPWStr)]string userAgent,
int flag);
...
IntPtr rets = Npr(reqHttp.Url.PathAndQuery,rAddr,Thread.CurrentThread.ManagedThreadId.ToString(),sessionID,reqGUID,
siteID,siteName,nodeStr,DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.GetCultureInfo("en-US")),reqHttp.RequestType,
HttpContext.Current.Response.StatusCode.ToString(), headers, cookieStr, uAgent,
flag); // Native Call from C#
...
在CppModule.dll中
EXTERN_C WCHAR* __cdecl Npr(WCHAR* testString,WCHAR* mname,WCHAR* threadID,WCHAR* sessionID,
WCHAR* rID,WCHAR* siteID,WCHAR* siteName,WCHAR* nodeOrder,
WCHAR* dateTime,WCHAR* rType,WCHAR* rCode,WCHAR* headStr,WCHAR* cookieStr,WCHAR* uAgent,int flag)
{ ... ... return wcharPtr;}
此Npr函数调用随机产生异常。异常消息是Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
在C#中的Npr函数调用的行号处。我更改了此功能Npr最近返回WCHAR *,从那里不断发生随机崩溃。我是否缺少任何互操作相关的封送处理或类似方法?
通常,在我的程序中,如果C ++函数返回字符串,我更喜欢在参数中传递StringBuilder,然后对其进行修改。
类似:
[DllImport("CppModule.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Npr"), System.Security.SuppressUnmanagedCodeSecurity]
public static extern void Npr(StringBuilder returnValue, [MarshalAs(UnmanagedType.LPWStr)]string moduleIDCur,
[MarshalAs(UnmanagedType.LPWStr)]string mName,
[MarshalAs(UnmanagedType.LPWStr)]string threadID,
[MarshalAs(UnmanagedType.LPWStr)]string sessionID,
[MarshalAs(UnmanagedType.LPWStr)]string reqID,
[MarshalAs(UnmanagedType.LPWStr)]string siteID,
[MarshalAs(UnmanagedType.LPWStr)]string siteName,
[MarshalAs(UnmanagedType.LPWStr)]string nodeOrder,
[MarshalAs(UnmanagedType.LPWStr)]string dateTime,
[MarshalAs(UnmanagedType.LPWStr)]string rType,
[MarshalAs(UnmanagedType.LPWStr)]string rCode,
[MarshalAs(UnmanagedType.LPWStr)]string headStr,
[MarshalAs(UnmanagedType.LPWStr)]string cookStr,
[MarshalAs(UnmanagedType.LPWStr)]string userAgent,
int flag);
...
Npr(returnValue, reqHttp.Url.PathAndQuery,rAddr,Thread.CurrentThread.ManagedThreadId.ToString(),sessionID,reqGUID,
siteID,siteName,nodeStr,DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.GetCultureInfo("en-US")),reqHttp.RequestType,
HttpContext.Current.Response.StatusCode.ToString(), headers, cookieStr, uAgent,
flag);
...
在c ++代码中:
EXTERN_C void __cdecl Npr(WCHAR * wcharPtr, WCHAR* testString,WCHAR* mname,WCHAR* threadID,WCHAR* sessionID, WCHAR* rID,WCHAR* siteID,WCHAR* siteName,WCHAR* nodeOrder, WCHAR* dateTime,WCHAR* rType,WCHAR* rCode,WCHAR* headStr,WCHAR* cookieStr,WCHAR* uAgent,int flag)
{ ... ... }