- PR -

VB.NET と C で可変長のデータを受け渡す

1
投稿者投稿内容
koiky
会議室デビュー日: 2006/11/11
投稿数: 3
投稿日時: 2006-11-11 02:10
VB.NET から C の DLL の関数を Declare 文でロードして動作させようとしています。

C の方の関数の機能としては、ポインタを引数として渡すと画像データを読み込んで
その分のメモリを確保し、先頭アドレスをポインタに格納します。
宣言は、

int CFunction( void* );

という感じです。

この場合、VB.NET の方では、引数としてどのような型を設定してあげればいいのでしょうか?

Public Declare Function CFunction Lib "CDLL.dll" ( ???? )

画像データというのは RAW 形式なので、単なるバイナリです。
しかし毎回データ量が違うため、C で動的にメモリを確保しています。

一応いろいろ調べてみたのですがうまくいかず、
どなたかご存知の方がいらっしゃいましたらご教示ください。
もしくは、「ここを調べなさい」というポインタでもありがたいです。

よろしくお願いいたします。
Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2006-11-11 10:49
本当に
>int CFunction( void* );
でしょうか?
これでは、Cだけで使っても、void*にアドレスは格納できないと思うのですけど。
(ポインタの値を格納するのであれば、 void** で受けないと値渡しになってしまう。)
コード:

int test(void* p) { p = malloc(1); return 1; }
int main(void) {
    void* p = NULL;
    int n = test(p);
    /* pはNULLのまま */
}



どっちにせよ、ポインタ型は IntPtr を使うのですかね。
確保した、領域長はどのように取得するのでしょうか?
戻り値ですか?
領域長がわかれば、Marshal.CopyあたりでVB側の配列にコピーするんでしょうかね。

また、確保した領域を解放する関数もC側に用意しておく必要があります。
VB側で解放することは普通はしません。
koiky
会議室デビュー日: 2006/11/11
投稿数: 3
投稿日時: 2006-11-12 02:35
Blue 様、書き込みありがとうございます。

引用:

本当に
>int CFunction( void* );
でしょうか?
これでは、Cだけで使っても、void*にアドレスは格納できないと思うのですけど。
(ポインタの値を格納するのであれば、 void** で受けないと値渡しになってしまう。)


ご指摘の通りですね。間違えていました。すみません。

引用:

確保した、領域長はどのように取得するのでしょうか?
戻り値ですか?
領域長がわかれば、Marshal.CopyあたりでVB側の配列にコピーするんでしょうかね。


領域長は別のところから持ってくるので、わかります。
VB側の配列をその領域長で確保してから、コピーするということですね。

引用:

また、確保した領域を解放する関数もC側に用意しておく必要があります。
VB側で解放することは普通はしません。


これについては、C 側に領域を開放する関数が用意されているので大丈夫です。
細かい部分についてもアドバイスいただき、ありがとうございます。

アドバイスをもとに、IntPtr, Marshal.Copy などを調べて作成してみます。
できたらご報告します。
koiky
会議室デビュー日: 2006/11/11
投稿数: 3
投稿日時: 2006-11-14 23:22
できました。

Public Declare Function CFunction Lib "CDLL.dll" (ByRef ptr As IntPtr) As Integer

として、得られたポインタとMarshal.Copy を使ってあらかじめ宣言しておいた配列に
データをコピーし、画像として表示することができました。


簡単にできたので意外でした。
そもそも調査不足で、VB.NET にポインタを扱う型があることを知らなかったのが
いけなかったのですが…。

大変助かりました。
ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)