调用C++;C#中的dll函数:结构、字符串和wchar_t数组

调用C++;C#中的dll函数:结构、字符串和wchar_t数组,c#,c++,struct,marshalling,dllimport,C#,C++,Struct,Marshalling,Dllimport,这里有一个简单的问题我需要解决,但它让我觉得我的头发变白了,因为我所有的尝试都返回相同的错误: “试图读取或写入受保护的内存。这通常表示其他内存已损坏。” 我有一个C++程序,它调用DLL。以下是相关代码: //function I need to call bool convertHKID_Name(char *code,RECO_DATA *o_data); //hkid //struct definition struct RECO_DATA{ wchar_t F

这里有一个简单的问题我需要解决,但它让我觉得我的头发变白了,因为我所有的尝试都返回相同的错误:

“试图读取或写入受保护的内存。这通常表示其他内存已损坏。”

我有一个C++程序,它调用DLL。以下是相关代码:

    //function I need to call
bool convertHKID_Name(char *code,RECO_DATA *o_data);    //hkid 

//struct definition
struct RECO_DATA{
    wchar_t FirstName[200];
    wchar_t Surname[200];
};

//how it is used in C++ code
CString code;
RECO_DATA data;
GetDlgItemText(IDC_CODE,code);
char _code[200];
WideCharToMultiByte(CP_UTF8, 0, code, -1, (char *)_code, 200, NULL, NULL);
ocr->convertHKID_Name(_code,&data)
<>现在,当我调试C++代码时,它做了正确的事情——将一些Unicode数据写入数据结构。< /P> 下面是我在C语言中的尝试#


我的猜测是,我没有正确封送RECO_数据结构,因为convertHKID_Name函数写入的就是这个结构。但是我该如何修复它呢?

我相信如果你

  • 更改
    convertHKID\u Name
    CharSet.Ansi
  • 从字符串中删除“ref” 参数
  • 传递
    字符串num
    直接转到
    convertHKID\u Name
    调用
    wideChartMultiByte

  • 我在C++中为非托管DLL编写了一个托管包装,但又被卡住了。 继续在这里


    还没有工作,我仍然认为封送结构肯定有问题。是什么原因直接传递字符串而不是REF,函数C++声明接受char *代码,我假设字符指针意味着值必须通过引用传递?字符串总是通过地址传递。“By reference”表示您将更新该值,并期望修改后的值返回给调用程序。哦,尝试将RECO_数据参数声明为“out”而不是“ref”--再次,您只希望它在一个方向上被封送。您还需要在C++中指定CurrnTrime= CalnValueNo.CDECL。如果这是一个成员函数,您将需要以不同的方式执行此操作。
        //my C# wrapper class
    public class cnOCRsdk
    {
        [StructLayout(LayoutKind.Sequential, Size=400, CharSet=CharSet.Unicode), Serializable]
        public struct RECO_DATA
        {
            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 200)]
            public string FirstName;
            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 200)]
            public string Surname;
        };
    
        [DllImport(@"cnOCRsdk.dll", CharSet=CharSet.Auto, EntryPoint = "?convertHKID_Name@CcnOCRsdk@@QAE_NPADPAURECO_DATA@@@Z")]
        public static extern bool convertHKID_Name(ref string num, ref RECO_DATA o_data);
    
        [DllImport("Kernel32.dll")]
        public static extern int WideCharToMultiByte(uint CodePage, uint dwFlags,
            [In, MarshalAs(UnmanagedType.LPWStr)]string lpWideCharStr,
            int cchWideChar,
            [Out, MarshalAs(UnmanagedType.LPStr)]StringBuilder lpMultiByteStr,
            int cbMultiByte,
            IntPtr lpDefaultChar, // Defined as IntPtr because in most cases is better to pass
            IntPtr lpUsedDefaultChar // NULL
            );
    }
    
    //my attempt to call the function from the dll
    cnOCRsdk.RECO_DATA recoData = new cnOCRsdk.RECO_DATA();
    string num = "262125355174";
    StringBuilder sb = new StringBuilder(200, 200);
    cnOCRsdk.WideCharToMultiByte(65001, 0, num, -1, sb, 200, IntPtr.Zero, IntPtr.Zero);
    string sbTostring = sb.ToString();
    //the next line generates the 'Attempted to read or write protected memory' error
    bool res = cnOCRsdk.convertHKID_Name(ref sbTostring, out recoData);