VB6からDLLへの構造体受け渡し

このQ&Aのポイント
  • VB6からCで作成したDLLに構造体を受け渡す方法について解説します。
  • 構造体にはLong型やDouble型、他の構造体も含まれており、C側も同様に設定する必要があります。
  • 構造体の一部の変数が文字化けしてしまう問題が発生することがあります。
回答を見る
  • ベストアンサー

VB6からDLLへの構造体受け渡し

VB6からCで作成したDLLに構造体を受け渡したいのですが上手くいきません。 構造体にはLong型やDouble型、それに他の構造体も含まれておりC側も同様にしているつもりなのですが文字化けしてしまいます。下記に入力しているのコードを記載しましたので分かる方がいましたら助けてください。 尚、下記の構造体の「method」までは問題無く取得できるのですが「success_interlinkage」のDouble型からの変数は文字化けした数字になってしまいます。宜しくお願い致します。 [VB側] Public Type PackageProcessingInfo_i brightness As Long contrast As Long smoothtype As Long smoothlevel As Long method As Long success_interlinkage As Double min_interlinkage As Double max_interlinkage As Double min_point As CvPoint max_point As CvPoint corner_point As CvPoint End Type Public Type CvPoint_i x as Long y as Long End Type [C側] typedef struct _PackageProcessingInfo { int brightness; int contrast; int smoothtype; int smoothlevel; int method; double success_interlinkage; double min_interlinkage; double max_interlinkage; CvPoint min_point; CvPoint max_point; CvPoint corner_point; } PackageProcessingInfo; typedef struct _CvPoint { int x; int y; } CvPoint;

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

Cの構造体の場合アクセスするメモリーアドレスの効率化のため要素の配置する場所が連続メモリー領域で無い場合があります 今回の場合一番大きな要素は doubleまたはCvPointで8バイト占有します この8バイトに各要素の境界をそろえるように配置されます したがって intの要素5個の後ろに使用しない4バイトがありその後ろにdoubleの3要素、CvPoint続くことになります 一方 VBのほうはそのようなことはお構いなしに構造体要素をそのまま並べます ここで4倍との差が生じ結果として doubleやCvPointがおかしくなるわけです 回避方法ですが 1) C側で構造体宣言部分に『#pragma pack(1)』などを指定しておく 2) intとdoubleの境界にダミーのint型のメンバーを置く 3) intメンバーを構造体の一番最後で宣言する などが考えられます また pragma packを使う際には #pragma pack( push, myHeader ) #include "myHeader.h" #pragma pack( pop, myHeader ) などとして構造体宣言したヘッダーファイルをはさむようにすると パッキング指定の互換性が保たれます この辺りは お使いのCコンパイラのマニュアルで確認しましょう

sadapapa
質問者

お礼

お返事ありがとうございます。 VB側で余計な事をして上手く受け渡しが出来なくなる事があるようですね!ご回答頂いた事を試してみたいと思います。ありがとうございました。

関連するQ&A

  • 構造体配列を引数とするDLL作成し、VBで呼ぶには?

    はじめまして。 VisualC++6.0でDLLを作り、VisualBasic6.0にて VisualC++の関数をコールし、構造体配列の値を 渡そうとしていますがうまくいきません。 どなたかよい知恵をお貸しください。 宜しくお願い致します。 下記に、VisualC++6.0とVisualBasic6.0のやりとり を記します。 *====Visual C++ 6.0側===== typedef struct _DLP_MSGDATA { int flg; char msg[504]; int tmp; } DLP_MSGDATA; _declspec(dllexport) int _stdcall SampSub(int data, DLP_MSGDATA *mdata) { return( 0 ); } *====Visual Basic 5.0側===== Declare Function SampSub Lib "test.dll" Alias "_SampSub@8" _ ( _ ByVal tlp_id As Long, _ ByRef mdata() As DLP_TLP_MSGDATA _ ) As Long Type DLP_TLP_MSGDATA flg As Long msg As String * 504 tmp As Long End Type Private Sub test() Dim mdata(0 To 130) As DLP_TLP_MSGDATA Dim aa As Long Call SampSub( aa, mdata ) End sub

  • VCの構造体【否 .Net】文字列

    http://okwave.jp/qa2526132.html での質問の発展です。 構造体の中に文字列を入れたいのです。 4の倍数にする必要がある、と聞いたので typedef struct {  char a[80];  int b;  int c; } Data_t; とし、VB側で Public Type vbData  a As String * 80  b As Long  c As Long End Type としましたが、うまく受け取れません。 どうかお力添えを。

  • DLLからEXEに構造体を渡すとき

    すいませんが、DLLからEXEに構造体を渡すときに どのようにしたらいいのでしょうか? 調べてみても EXE→DLLには載っているのですが、 DLL→EXEには調べ方が悪いのかわかりませんでした。 よろしくお願いいたします。 typedef struct _KOUZOU { int a; int b; } KOUZOU; (ここをどのように?) CALLBACK test() { KOUZOU kouzou1; kouzou1.a=1; kouzou1.b=2; return (ここをどのように?); }

  • 構造体の中の構造体

    typedef struct number{ int x; struct number *next; }Num; 初心者な質問で申し訳ないんですが、構造体の中に構造体があるのはどう解釈していいんでしょうか? typedef struct number{ int x; int y; }Num; の場合はNum a,b;がint a.x,a.y,b.x,b.yとなるのは分かるんですが・・・

  • 構造体のあるメンバを基準にソートするには?

    以下のように定義した構造体(下の構造体は入れ子になっている)を必要な時に動的に割り当てた後(デー多数は不定)、たとえば、商品価格を基準に降順、昇順に並び替える機能を追加したいのですが、どのように解決したらよろしいでしょうか? /* 現在の日時を格納する構造体 */ typedef struct time_type{ int year; int month; int day; }time_type; /* 商品の情報を格納する構造体 */ typedef struct shohin_type{ int code; /* 商品コード */ int price; /* 商品価格 */ char *name; /* 商品名 */ int flag; /* フラグ */ struct time_type date; /* 登録日 */ struct shohin_type *before; /* 前の構造体のアドレス */ struct shohin_type *next; /* 次の構造体のアドレス */ }shohin_type;

  • 構造体の纏めの後について……。

    以前、『構造体の纏め方』と言うタイトルで質問した者です。 早速本題に。 // --------------- 構造体・鋳型宣言 --------------- typedef struct tagABC {    int Dog;    int Cat; } ABC; // ----------------------------------------------- // --------------- 構造体実体宣言 ----------------- ABC Point1[ 20 ][ 20 ] = {   {     { 10 , 11 },     { 20 , 21 },     { 30 , 31 }   },{     { 100 , 101 },     { 200 , 201 }   } },    Point2[ 20 ][ 20 ] = {   {     { 1000 , 1001 },     { 2000 , 2001 }   } }, /************************************************/ /*        『ココが難題!!』        */ /************************************************/    *DBase[] = { Point1[ 0 ] , Point2[ 0 ] }; // ----------------------------------------------- さて、呼び出し側のソースコードは、 Point1[ 1 ][ 0 ] とすれば、 { 100 , 101 } を返してくれます。 *以後、この値が欲しいとして話を進めます しかし、 ( DBase + 0 )[ 1 ][ 0 ] と呼び出した場合、突然予定通りの値を返してくれません。 (コンパイルとビルドは通る) デバッガでメモリ上を見てみると、期待している値(上記)を呼び出す為には、 ( DBase + 0 )[ 0 ][ 20 ] となっており、普通ならばアクセス出来ない場所を指定しなければならなく、とても不思議な現象が起こっています。 因みに、 ( DBase + 0 )[ 1 ][ 0 ] と指定すると、結果的には、 Point2[ 0 ][ 0 ] を参照しているのと同じ現象が起こります。 この現象をどうにかして二次元配列で期待した値を呼び出せる方法を御教授御願いします。 使用コンパイラ:BCC 5.5.1

  • 構造体 アドレス

    VC++6 こんにちは。構造体のアドレスを文字列ポインタで操作することに悩んでいます。下にソースの一部を書きます。 typedef struct{   char code[100];   int type; }AAA; typedef struct{   double method[4][3];   int area; }BBB; 複数の構造体があり、 BOOL CTestApp::File_Check(){  AAA aaa; ~  db.DB_regi(2, (char *)&aaa); ~ } void CData::DB_regi(int key, char *buff) {  switch(key){ ~  case 2:   sss.push_back(buff);  //vector<char *> sss;   break; } で、データを登録し、 int CTestApp::Data_Check() { ~  AAA aaa;  db.DB_get(2, (char *)&aaa); ~ } void CData::DB_get(int key, char *buff) {  switch(key){ ~  case 2:   buff = sss[i];   break; ~ } で、構造体のアドレスを取得しようと思ったら、取得できませんでした。 //DB_getの中では、aaa = (AAA *)buff;とすれば指定の構造体を取得できる。 DB_get関数をどのようにしたら、Data_Check()で、登録した構造体を取得できるのか教えてください。長くなってすみません。

  • ヘッダファイルと構造体

    typedef struct{ float x; float y; float z; }Point; typedef struct { struct Point p1; struct Point p2; }Rect; とヘッダファイルに入力しコンパイルしてみると struct Point p1; struct Point p2; のPointが未定義の構造体とエラーが出ます。 どのように書けばいいのでしょう??

  • 動的配列の構造体の受け渡しについて

    動的配列の構造体の受け渡しについて教えていただきたいです。 typedef struct{ int class; int **matrix; }pattern_struct; という構造体を用意しました。 メイン側で int main(){ pattern_struct *sample,*prototype; 省略 for(k=0;k<9;i++){ for(i=0;i<height;i++){ for(j=0;j<width;j++){ prototype[0].matrix[i][j]=sample[k].matrix[i][j]+prototype[0].matrix[i][j]; } } for(i=0;i<height;i++){ for(j=0;j<width;j++){ prototype[1].matrix[i][j]=sample[k].matrix[i][j]+prototype[1].matrix[i][j]; } }     ~9まで続きます~ } 省略 } 少し変えていますが、このようなプログラムを記述しました。 記述を省略するためにmallocで作成した構造体配列の足し算をする関数を作りたいのですが、どのように記述するべきなのでしょうか。

  • 構造体メンバ 構造体ポインタ 値代入

    typedef struct _test_t{ int aaa; int bbb; } test_t; typedef struct _globalData{ int xxx; test_t* pTestData[256]; } globalData_t; globalData_t globalData; int main(){ test_t testData1 = {1,1}; test_t testData2 = {2,2}; *globalData.pTestData[1] = testData1; /* (1) */ globalData.pTestData[2] = &testData1; /* (2) */ } 上記のようなグローバルデータの構造体globalData のメンバの構造体配列にtest_t型の構造体を格納し保持するには、 (1)、(2)のどちらが正しいでしょうか?

専門家に質問してみよう