从C#模块调用C ++函数会引发随机崩溃

问题描述 投票:0回答:1

我的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# c++ interop marshalling
1个回答
0
投票

通常,在我的程序中,如果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)
{ ... ... }
© www.soinside.com 2019 - 2024. All rights reserved.