VB.NET2003からVC++6.0で作ったAPIを呼ぶ際に、固定長の引数を渡すには?

解決


どぅぅぅい  2003-08-04 20:32:46  No: 78893  IP: [192.*.*.*]

初歩的なことかもしれませんが、教えてください。
現在、

Public Structure A
        <VBFixedString(4), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=4)> Public LEVER As String 'バージョンレベル
        <VBFixedString(5), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=5)> Public CDUSR As String '利用者コード
            End Structure

以上のように構造体を宣言し、
A.LEVER ="1000"
A.CDUSR ="ABCDE"
のように値を代入して、VC++6.0で作成したAPIに渡し、APIの中できちんと値が
渡っているか確認すると、それぞれの値の一番最後の文字がNULLになって渡ってしまいます。原因もしくは回避方法を知っている方がいらっしゃれば教えていただけないでしょうか。
よろしくお願いします。

編集 削除
魔界の仮面弁士  2003-08-05 04:10:17  No: 78894  IP: [192.*.*.*]

Null終端でない文字列を受け渡す場合は、Char配列を利用してください。


************ 呼び出される側となるC++のヘッダソース ************

// とりあえず今回は、TCHARが _MBCS側でコンパイルされる物とします。
typedef struct userTypeStruct {
   TCHAR LEVAR[4];
   TCHAR CDUSR[5];
} userType;

STDAPI_(VOID) ReceivesUserDefinedType(userType FAR *u);

************ 呼び出す側となるVBモジュールのソース ************

Imports System.Runtime.InteropServices

Module Module1
  Public Declare Auto Sub ReceivesUserDefinedType Lib "..\..\Cpp\Debug\Cpp.dll" _
    Alias "ReceivesUserDefinedType" (ByRef bstruct As UserDefinedType)

  '構造体メンバの最配置を行わない。シングルバイトパッキングを使用。マルチバイト文字セットを使用。
  <StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)> _
  Public Structure UserDefinedType
      <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.ByValTStr, SizeConst:=4), VBFixedArray(3)> _
      Public LEVER() As Char  'バージョンレベル
      <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=5)> _
      Public CDUSR() As Char  '利用者コード

      Public Sub InitStruct()
          LEVER = "1000".ToCharArray
          CDUSR = "ABCDE".ToCharArray
      End Sub
  End Structure

  Sub Main()
    Dim UDT As UserDefinedType
    UDT.InitStruct()
    ReceivesUserDefinedType(UDT)
  End Sub

End Module

編集 削除
魔界の仮面弁士  2003-08-05 04:20:30  No: 78895  IP: [192.*.*.*]

おっと、『利用者コード』の方の属性定義が間違っていました。
『バージョンレベル』と同様、ByValArrayを与えてやって下さい。

<MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.ByValTStr, SizeConst:=5), VBFixedArray(4)> _
Public CDUSR() As Char  '利用者コード

編集 削除
どぅぅぅい  2003-08-05 17:18:58  No: 78896  IP: [192.*.*.*]

魔界の仮面弁士さんの言うとおり、char配列を利用したらうまくいきました!
ありがとうございました。

編集 削除