3

ライブラリの C++ ヘッダーには、次のコードがあります。

#define STR_DATE        24+1    
#define STR_SIZE        32+1
#define STR_SSIZE       64+1
#define STR_MSIZE       128+1
#define STR_LSIZE       1024+1
#define STR_IPSIZE      15+1
#define STR_MOD_SIZE    20+1
#define STR_AGESIZE     4+1
#define STR_GENDERSIZE  1+1

typedef struct ADO_PINFO{   
    char    P_ID[STR_SSIZE];        
    char    F_Name[STR_SSIZE];          
    char    M_Name[STR_SSIZE];          
    char    L_Name[STR_SSIZE];          

    char    Reg_Num[STR_SSIZE];         
    UINT    nGender;                    
    UINT    nAge;                       

    COleDateTime BirthDay;              
    char    csBirthDay[STR_SIZE];       

    COleDateTime V_Date;                
    char    csV_Date[STR_SIZE];         

    char    Address[_MAX_PATH];         
    char    SubAddress[_MAX_PATH];      

    char    Telephone[STR_SIZE];        
    char    H_Phone[STR_SIZE];          

    char    csMail[STR_SSIZE];
    char    csPicName[_MAX_PATH];       
    COleDateTime InDate;
    char    csInDate[STR_SIZE];
}*PADO_PINFO;

_ADODLL long ADO_AddPatientData(const ADO_PINFO &pPatientInfo);

dll を C# アプリケーションにインポートしようとしています。

[StructLayout(LayoutKind.Sequential)]
public struct ADO_PINFO
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string P_ID;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string F_Name;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string M_Name;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string L_Name;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string Reg_Num;

    public uint nGender;

    public uint nAge;

    public DateTime BirthDay;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string csBirthDay;

    public DateTime V_Date;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string csV_Date;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string Address;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string SubAddress;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string Telephone;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string H_Phone;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string csMail;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string csPicName;

    public DateTime InDate;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string csInDate;
}

public class VatechLibrary
{
    [DllImport("AdodllE.dll")]
    public static extern long ADO_AddPatientData(ref ADO_PINFO patientInfo);
}

しかし、私がそれを呼び出すと:

var pInfo = new ADO_PINFO();
pInfo.P_ID = "77";
pInfo.F_Name = "name";

var res = VatechLibrary.ADO_AddPatientData(ref pInfo);

AccessViolationException が発生します。私は何を間違っていますか?

4

5 に答える 5

2

私が見ることができる問題:

  1. COleDateTimeフィールドのマーシャリングが間違っています。これCOleDateTimeは、C++ クラスであり、バイナリ相互運用の有効な型ではないためです。そして.netDateTimeは確かに一致しません。それは確かにあなたのアクセス違反の原因です.
  2. longこの関数は、 Windows では 32 ビット幅の C++ を返します。C#longは 64 ビット幅であるため、C# 関数の宣言は間違っています。C# の戻り値を に変更しintます。
  3. C# の呼び出し規約はstdcall. C++ 関数の呼び出し規約は何ですか? に含まれていると考えられ_ADODLLます。であることを確認する必要がありますstdcall。呼び出し規約が指定されていない場合は、cdecl.

との問題COleDateTimeは、ここで大きな問題です。他は簡単に直ります。についてはそうではありませんCOleDateTime。C++ コードを変更して、相互運用に適した日付の表現を受け入れることができます。項目 1 の問題に対処するために C++ コードを変更できない場合、ソリューションには、混合モードの C++/CLI ラッパーを作成することが含まれます。

于 2013-11-12T16:41:10.443 に答える
0

のドキュメントからUnmanagedType.ByValTStr

構造内に表示されるインラインの固定長文字配列に使用されます。ByValTStr で使用される文字型は、包含構造に適用される System.Runtime.InteropServices.StructLayoutAttribute 属性の System.Runtime.InteropServices.CharSet 引数によって決定されます。配列のサイズを示すには、常に MarshalAsAttribute.SizeConst フィールドを使用します。.NET Framework ByValTStr 型は、構造体内の C スタイルの固定サイズ文字列のように動作します (たとえば、char s[5])。

あなたの文字セットは何ですか?私の推測では、ユニコードです。

于 2013-11-12T15:16:13.437 に答える
0

構造を確認する必要があります。タイプ COleDateTime はクラス C++ であり、相互運用する属性を直接作成する必要はありません。アクセスする必要がある項目を確認し、レイアウトをやり直してください。

于 2013-11-12T17:02:01.877 に答える