• ベストアンサー

VC6.0で作ったライブラリをVBで呼び出したい

Vc++6.0で作ったライブラリをVBで呼び出そうとしています。 void*型の引数を呼び込みたいのですが、宣言部でどのように書けばよいのでしょうか? 呼び出し時引数をどのような形で渡せば良いのでしょうか? また返り値をPVOID型とするとどのように宣言部で書いて、呼び出したらよいのでしょうか? 例 void DeleteDllClass( PVOID oBj );という関数を   VBから呼び出すと?   PVOID CreateDllClass();をVBから呼び出すと? 調べてみましたがイマイチ分からなくて・・・・

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

  • ベストアンサー
回答No.3

新たな関数が出てきましたね・・・ そのCreateDllClassで作成したオブジェクトはポインタのままの利用であれば、全てLongで事が足りると思います。 Private Declare Sub CreateDllClass Lib "C製.DLL" (ByRef pObj As Long) Private Declare Sub DeleteDllClass Lib "C製.DLL" (ByVal pObj As Long) Sub Test() Dim l_ptr As Long Call CreateDllClass(l_ptr) Call DeleteDllClass(l_ptr) End Sub また、別途オブジェクト変数を宣言し利用しているのであれば Private Declare Sub CreateDllClass Lib "C製.DLL" (ByRef pObj As Any) Private Declare Sub DeleteDllClass Lib "C製.DLL" (ByVal pObj As Long) Sub Test() Dim l_obj As Object Call CreateDllClass(l_obj) Call DeleteDllClass(ObjPtr(l_obj)) End Sub などなど、、、、、 未検証なので、多少間違いはあるかもしれませんが、方向は違っていないはず^^; >さすがにVBにはポインタという概念がない?からむりでしょうか? 「ポインタ=番地」 という概念さえ持っていれば、VBでも応用はいくらでも利きます。 今回質問者さんは、Cの宣言だけを公開して質問されていますが、インターフェースを通じて取得した「物」で何をするかで、VB側で最も適した処理方法が異なると思います。 部分的に公開して質問されても、マクロ的に「Longで宣言」という変換方法以上のことは、言うことができません。 http://okwave.jp/kotaeru.php3?q=1267832

maronii_now
質問者

お礼

ありがとうございます。 とある取引先にあるアプリを提供したのですがその機能をライブラリ化して欲しいと頼まれました。 スレッドを立ち上げて複数のRWにアクセスするのでCのほうが早く作りやすいのでCで作りました。 しかし取引先はおそらくCを使ってないかと思います。 なのでVBのサンプルをつけておけば分かりやすいだろうし(うちへの質問も減る)と思っています。 関数は (1)DLLクラス作成関数 (2)DLLクラス削除関数 (3)RWからICのデータを読み込む (4)ICのデータをCSVに出力する 機能を持ち、(3)のデータをDLLクラス内で保持し(4)で出力できるようにしたいと思っています。 なので (1)VOID CreateDllClass(PVOID *DllClass); (2)VOID DeleteDllClass(PVOID *DllClass); (3)LONG ReadData(PVOID *DllClass); (4)LONG OutputCsvFile(PVOID *DllClass); というインターフェースにしました。 ((3)(4)の返り値は実行結果) これをVBで呼び出すのに苦労していました。 アドバイスのおかげで何とかできました。 DeleteDllClassの引数の意味はオブジェクトへのCreateDllClassで作成したクラスへのポインタの意味でした。 取引先より特定機能をライブラリ化したものが欲しいといわれまして。 ちなみに ともに引数はクラスへのポインタとしたとき void CreateDllClass( PVOID * pObj ); void DeleteDllClass( PVOID pObj );

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

回答No.4

>とある取引先~Cで作りました。 ふむふむ >しかし取引先はおそらくCを使ってないかと思います。 !! >なのでVBのサンプルをつけておけば分かりやすいだろうし(うちへの質問も減る)と思っています。 なるほどです。苦労がよくわかります。 ノウハウの伝達は口頭や書面より、「動くサンプル」がベストですもんね^^ >何とかできました。 レスがないので、不安だったのですが、いい結果を聞くことができて非常にうれしいですよー お互い、今後も多種多様なスキルアップに努めていきましょうね! それでは^-^

maronii_now
質問者

お礼

ありがとうございます。 無事、客先にサンプルを出すことが出来ました。 客先が米国なので出来るだけ質問が来ないことを祈っているのですが(笑) そもそもアプリをActiveXで使えるようにしろ、そんなの簡単だろという依頼でしたし・・・

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

>MFC Classを削除 オリジナルの開発環境構成ツールかな?(と勝手に推測と・・・) 私が知りたいのは 「DeleteDllClass」の機能というより、「DeleteDllClass」の引数の意味です^^ http://www.microsoft.com/japan/developer/library/jpwinpf/_win32_getexitcodeprocess.htm を見ると、引数の一つ一つに意味が記されていますよね? このように、関数本体の機能も大事ですが、インターフェースの意味が最も重要なのです。 でも解決したっぽいのでよかったです。 あーだこーだと言っておりますが、今度似た様な事がありましたら、質問をする際の参考にしてもらえたら幸いです。 さらに参考までにですが、Cがアドレスを求めているのであれば、全てLongで切ることが可能です。 ※「全てLongにするべき」と言っているわけではありません。 #1でも述べたように「varptr,objptr,strptr」で、渡す変数のアドレスを求める事ができます。 これらを覚えていたら、VB6⇒C製.dllの呼び出しは、ほぼ可能だと思います。 ただ、汎用的にしたいのであれば、全てAnyで切ってしまえば100%と言っていいぐらい可能かと、、、 それをどう利用するかは、その都度DLLの特性を調べる必要がありますが^^;

maronii_now
質問者

お礼

ありがとうございます。 DeleteDllClassの引数の意味はオブジェクトへのCreateDllClassで作成したクラスへのポインタの意味でした。 取引先より特定機能をライブラリ化したものが欲しいといわれまして。 ちなみに ともに引数はクラスへのポインタとしたとき void CreateDllClass( PVOID * pObj ); void DeleteDllClass( PVOID pObj ); とすると、 CreateDllClassで作ったPVOID * pObj の値を DeleteDllClassの引数に渡すにはどうすればよいのでしょう? さすがにVBにはポインタという概念がない?からむりでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

結果をいうと、変数のポインタを渡せばいいだけなのですが、、、 そのCで作られたDLLに、VB側からどのような型の変数を渡すつもりですか? longで宣言をしておいて、varptr,objptr,strptrのいずれかを利用するか、anyで宣言をしておいて、オブジェクト変数をそのまま渡せばよいようなパターンも想像できます。 なので、そのDLLの仕様がわからなければ、答えようがありません。

maronii_now
質問者

お礼

ありがとうございます。 オブジェクトへのポインタってどういう変数にするか迷ってまして。 long型で出来ました。 ちなみに CreateDllClassでMFC Classを作成し,DeleteDllClassでMFC Classを削除するという構成にしています。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VB6からVC6で作成したDLLの関数を呼び出すときに注意すること

    VB6からVC6で作成したDLLの関数を呼び出すときに、型について気をつけないといけませんが、VB6でint型のものはVC6ではshortにしないといけないのでしょうか?マシンやOSや開発環境(例えばVS2005やGCC)により違ってくるのでしょうか? VB6とVC6でやり取りする場合の型について知りたいです。 あと、ActiveXのDLLの場合は関数にアクセスするのではなく、COM(という概念がわかっていないのですが)を使うのですか?

  • VC++のDLLをVB6.0からVB.NETへ移行する方法

    はじめて投稿します。 今、現状VB6.0のプログラムで使用しているVC++のDLLを VB.NETで使用できるように、VB.NETのソースの改修をしています。 (開発環境は、VisualStudio.NET 2003) たいていのDLLは、DllImportを行うことで VB.NETから使用できることを確認しました。 /*--(例)------------------------------------------*/ Imports System.Runtime.InteropServices <DllImport("DLLTest.dll")> _ Private Shared Function DLLTestMethod() As Integer End Function /*------------------------------------------------*/ しかし、苦戦しているDLLファイルがあって、 そのソースを見ると、COMで実装されているようで、 コンパイルしたらタイプライブラリファイルが作成されています。 またDLLのレジストリも登録されているようです。 VB6.0でどう使われているか確認したところ、 そのDLLの参照設定をしていて、 "Public obj As New クラス名"でクラス宣言した後、 obj.関数名()で処理を行っています。 VB.NETでいろいろ試行錯誤してみましたが 参照設定はできるものの、その後で手詰まりになっています。 (参照設定しても、灰色になっているクラス名が存在するので 正しく設定できているかも怪しい状態) (1)----------------------------------------------- 参照設定後、オブジェクトブラウザから見えるクラスをNewして そのメンバ関数を使用する方法 -------------------------------------------------- (結果) レジストリ登録をしていないと 「CLSID{・・・}のCOMオブジェクトが有効でない」云々というエラーに。 それを受けて手動で該当するDLLのレジストリ登録を行った後だと 「オブジェクト参照がオブジェクトインスタンスに設定されません」というエラー。 (ということは、クラス生成に失敗している?) (2)----------------------------------------------- 上記のようにDllImportで実装する方法 (ちなみにそのDLLがエクスポートしている関数は DllCanUnloadNow, DllGetClassObject, DllRegisterServer, DllUnregisterServerの4つ) -------------------------------------------------- (結果) DllGetClassObject以外については関数を呼ぶことができている。 DllGetClassObjectは、引数設定に苦戦して今のところうまくいっていない状態。 (3)----------------------------------------------- インスタンス生成ができていないようなので どこかで調べて見つけてきたCoCreateInstance関数を使用する方法 -------------------------------------------------- (結果) これも引数に何を渡してよいかわからず試行錯誤中。 DLLの読み込みの時点でこけているかと予測して そのあたりが解決すればよいのかな・・・といろいろ試していますが WindowsプログラミングやCOMがよくわかっていないので 何が正解で何が間違っているのかさっぱりわからず、 周りに聞いても精通している人がいないためどうしようもなくなっています。 どんな些細な手がかりでもよいので 突破口になりそうなアドバイスがあれば教えてください。 よろしくお願いします。

  • VB.netでのVC++呼び出し引数の順番

    VC++で作成されたDLLをVB.NetにてそのDLLを呼び出すアプリを作成して います。以下のパターン2では問題なく動作しますが、パターン1では DLL側で見たときにchar変数に正しく値が入りません(NULL)になる。 パターン1とパターン2の違いは引数の順番です。 開発環境:VisualStudio2008 OS:WindowsXP SP2 パターン1(この場合はNG)  VC++側の宣言   extern "C" __declspec(dllexport) void func1(int i,char*s)  VB.Net側の宣言   <System.Runtime.InteropServices.DllImport("func.dll")> _   Public Sub func1(ByVal i As Long, ByVal s As String)   End Sub パターン2(この場合はOK)  VC++側の宣言   extern "C" __declspec(dllexport) void func1(char*s,int i)  VB.Net側の宣言   <System.Runtime.InteropServices.DllImport("func.dll")> _   Public Sub func1(ByVal s As String ,ByVal i As Long)   End Sub VC++側がパターン1で作成さているため、VC++側を修正をしないで 正常に動かすことは可能でしょうか? よろしくお願いします。

  • C言語からVBに

    質問させていただきます。 今まで、VC6.0で作成した関数をVB6.0又はVB.NETで作り変えます。 そこで、呼び出し元(VC6.0:引数あり)から呼び出し先(VB6.0又はVB.NET)の関数を呼び出すには、どうしたらいいでしょうか? 現状:呼び出し元 VC6.0     呼び出し先 VC6.0 今回:呼び出し元 VC6.0    呼び出し先 VB6.0(ソースのみ:フォームなし) 宜しくお願いします。

  • プロトタイプ宣言について

    C言語で関数を作成しプロトタイプ宣言するときの質問です。 関数実体の引数に構造体のポインタを宣言します。 プロトタイプ宣言には,構造体のポインタを宣言したのと同じ位置にvoid *を宣言します。 関数実体とプロトタイプ宣言は,異なるファイルです。 このように作成した関数は,VC++2008では,コンパイルできるのですが, なぜ関数実体の宣言とプロトタイプ宣言の型が異なるのにコンパイルできるのでしょうか? また,この関数を別ファイルの関数から呼び出した場合,正しく引数を理解し,正しく処理されます。 これは,言語仕様として正しい書き方なのでしょうか? それとも環境依存の書き方なのでしょうか? ご存知の方がいましたらお答えお待ちしています。

  • Voidポインタで受け取った変数の型を調べる方法

    あるライブラリの関数を利用しようとしたのですが、その関数の引数にVoidポインタがあり、どういう型のデータを格納したのかわかりません。このポインタのアドレスに格納されたデータの型を調べる関数なり方法なりというのはあるのでしょうか。 Voidポインタというのは型を問わずに受け取れるというのは利点ですが、受け取ったものがあらかじめなんだかわからない場合はどうするのでしょうか。よろしくお願いします。

  • Cで作成したDLLをVBで呼出

    Cで作成したDLLの関数をVB6.0から呼び出す事ができず、悩んでおります。 ご教授お願いします。 どの様な関数を呼び出そうとしているのかというと、以下の通りです。 <DLL Cで作成(コンパイラVC6)> void WINAPI hoge(BSTR pgname,BSTR fmt,...){ ~処理~ } /* 宣言では頭にDLLExport*/ <呼出側 VB6.0で作成> '宣言 Public Declare Function hoge Lib "hoge" _ (ByRef pgname as String , _ ByRef fmt as String , _ ParamArray args()) '呼出 call hoge("foo","baa","array1",2) この様なコードを書いております。 C側、VB側ともに固定数の引数にしてみたところ、 通ったので「ParamArray args()」の定義が違うのではないか・・・?と思っているのですが、 どの様に宣言したらよい物なのでしょうか? もしくは、そもそも全然違う箇所を間違っているのでしょうか? 宜しくお願いします。 ※ 説明の足りない箇所があれば、仰ってください。

  • VB 関数

    初めまして。 VB初心者なので,簡単な質問なのかしれませんが御願いします。 C言語で,   int      main        (void) 戻り値の型    関数名      戻り値なし と書きますが,これと同じ意味を持つプログラムをVBで書くとどのようになりますか? 関数の作り方がまだわかってないので教えていただけますか? 宜しく御願いします。 

  • VC++6.0からVB.NETで作成した関数を呼ぶことができますか?

    VB.NET(Visual Basic 2005 Express Edition)でクラスライブラリ(AAA.dll)を作成し、BBBというModuleにCCCというFunctionをひとつ作成しました。 そのFunctionをVC++6.0で作成したプログラムから呼び出すことは可能でしょうか?また、可能な場合はどのような手順で呼び出すことができるのでしょうか? ■VB6.0でDLLを作成した場合 DLLのファイル名とFunction名さえ指定すればVC++6.0よりLoadLibrary、GetProcAddress関数を使用して呼び出せる。 ■VB.NETでDLLを作成した場合 DLLのファイル名+Module名+Function名という構成になってしまい、従来のLoadLibrary、GetProcAddress関数ではModule名が指定できないように思われるのですが・・・どうなんでしょう。 ご存知の方いらっしゃいましたらご教授お願いいたしますm(_ _)m

  • VB6.0を使用しています

    VB6.0を使用しています VC6.0でdefファイルで宣言してDLLを作成し VBのEXEよりDLLをCALLしています。 VBではDLLの関数をDeclareで宣言しています。 問題なのは ちょっと前まで問題なく動いたDLLですが 新規にDLL関数を追加したら EXEではちゃんと呼び出して処理を行なってくれておりますが VBのデバッグ起動で呼び出すと、その新規のDLLの関数がありませんと メッセージを通知して止まってしまいます、 EXEでは動くのにデバッグ起動ではだめなんでしょうか??不思議です もし、ご存知の方がいらっしゃいましたら教えてください。