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

このQ&Aのポイント
  • Cで作成したDLLの関数をVB6.0から呼び出す方法について教えてください。
  • VB6.0からCで作成したDLLの関数を呼び出す際、ParamArray args()の宣言方法について教えてください。
  • C側とVB側の引数の定義に問題がある可能性があります。正しい引数の定義方法について教えてください。
回答を見る
  • ベストアンサー

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()」の定義が違うのではないか・・・?と思っているのですが、 どの様に宣言したらよい物なのでしょうか? もしくは、そもそも全然違う箇所を間違っているのでしょうか? 宜しくお願いします。 ※ 説明の足りない箇所があれば、仰ってください。

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

  • ベストアンサー
  • 0KG00
  • ベストアンサー率36% (334/913)
回答No.1

http://hata.cc/docs/DLL/3.html リテラル定数でなく、変数にしてbyval渡しにすればよいのでは。

sekidoutyokka
質問者

お礼

おかげさまで解決致しました。 引数に関して、仰る通り「byval渡し」で解決致しました。 しかしながら、C側でvsprintfでは変数型の違いから上手く受け取れなかった様です。 (ここでおかしくなっておりました) なので、fmtの%dやら%sやらを読み込んで、switchで型ごとにva_argで一つずつ取得することに致しました。 これは質問に書いておりませんでしたので、 分かろう筈がないですね^^;すいません。 Cの関数から呼び出した限りでは上手くいっていたので、問題ないはずと決めてかかっておりました。 ありがとうございました。

sekidoutyokka
質問者

補足

アドバイス有難うございます。 実際に作成した呼出側関数では、 それぞれを変数に格納した後、呼び出しております。 ByRef,ByValとも試してみたのですが、上手く行きませんでした。

関連するQ&A

  • DLL VBとC++

    VBAからVC++2005のDLLを呼び出すプログラムを書いています。 VB側で作成したcpp_proc関数を呼ぶとVBアプリ自体が落ちました。 DLLのreturnの直前に以下のMessageBoxで表示させるとそこまでは表示され、 リターンを押すと、落ちました。 VB側の引数の値 String * 8192が悪いのでしょうか? return直前まで動作していたので、DLLの戻り値に何か原因があるのでしょうか? ついでの質問ですが、DEFの @1は無くても動くのでしょうか? 意味が知りたいです。 // ----- C++ (DLL側) ----- int __stdcall cpp_proc(LPCSTR inp, LPSTR out) { ... 省略 MessageBox(0, "ここまで通過", "debug", MB_OK); return 0; } // ----- DEF ----- LIBRARY "example" DESCRIPTION 'テスト' EXPORTS ; 明示的なエクスポートはここへ記述できます cpp_proc @1 '----- VB側 ----- Public Declare Function cpp_proc Lib "example.dll" _ (ByVal inp As String, ByRef out As String) As Integer Public Sub Test() Dim ret As Integer Dim inp As String Dim out As String * 8192 ret = cpp_proc(inp, out) MsgBox("ret=[" & Cstr(ret) & "]"); End Sub

  • Cで作成したDLL関数をVBから呼ぶ(.NET)

    以前の質問に「Cで作成したDLL関数をVBから呼ぶ」(QNo.1703839)がありますが、下記のコードを見るとVB6での内容だと思います。 Dim keydata As String * 128 keydata = String$(128, Chr(0) & Chr(0)) VB.NETでVC++のDLLで変更した文字列を受けたいのですが、 どのようにすればよいのでしょうか? VB.NET2003 <DllImport("DllTest.dll")> Private Shared Function _ Test(ByVal s1 As String) As String End Function Private Sub btnTest_Click(...) ... Dim s1 As String = "abc" Dim s2 As String Dim s3 As String s2 = Test(s1) MessageBox.Show(s2) ' "1"が表示される s3 = StrConv(s2, VbStrConv.None) MessageBox.Show(s3) ' 同じく"1"が表示 end sub VC++のDLL extern "C" __declspec (dllexport) BSTR __stdcall Test(char* s1) { AfxMessageBox(s1); // "abc"が表示される OK strcpy(s1, "123"); CString s2; s2 = "123"; return s2.AllocSysString(); } また、文字列に全角を含めても大丈夫でしょうか? Unicodeの変換処理を行う必要があるのでしょうか? よろしくお願いします。

  • Cで作成したDLL関数をVBから呼ぶ

    以前にあった「Cで作成したDLL関数をVBから呼び 引数渡し方法」を試したのですがVB側でデータが受け取れません。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=711327 C側での値設定がわるいのでしょうか? VB側 Public Declare Function testAP Lib "C:\bin\test.dll" (ByVal lpKeyData As String) As Long --------------------------------------------------------------------------- Dim lngRc As Long Dim keydata As String * 128 keydata = String$(128, Chr(0) & Chr(0)) lngRc = testAP(keydata) VC側 __declspec(dllexport) long __stdcall testAP(char *lpdata){ →C側でlpdataに値を設定する lpdata="ABCDEF"; }

  • VBからMFC-DLL呼び出し

    VC++6.0でDLLを作成してVBから呼んでいます。 VC++6.0 __declspec(dllexport) BSTR WINAPI FunA() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strA = _T("This is the テストです。.愛する</CsvData>"); return strA.AllocSysString(); } VB6.0 Private Declare Function FunA _ Lib "Communication.dll" () As String Dim strRet As String strRet = StrConv(FunA(), vbFromUnicode) これを実行すると 『This is the テストです。.愛す?</CsvData>』 がstrRetに格納されます。 『愛する』→『愛す?』になってしまうんですが、 どうしてでしょうか。

  • dllを使用しVB側に文字列を返す2

    No.280310の質問の続きになってしまいますが 「VCで作ったdllを使用し VBに文字列を返すことはできますか」 でVCで作ったdllをVBを呼び出す事ができるようになりました。 Declare宣言で疑問に思ったのですが Declare Function TxtCnt Lib "hoge.dll" (ByVal a As String) As Long aはなぜ値渡しなのでしょうか? 変数が書き換えられて戻ってくるので、byrefで指定していました。 それが問題が起こしていた原因一つでした。 ちなみにint型の数値をポインタで渡した場合はbyrefでうまくいきます。 ご教授願います。

  • VB6.0からVB.NETへの移行

    VB6.0から.NETへの移行を行うこととなりましたが、C++で作成したDLL呼び出し方法がわからず悩んでいます。 C++側で作成したDLLは修正が出来ない為、.NET側のみで修正しなければならない状況です。 VB6.0側のプログラムは以下のような感じです。 Public FName() As String Declare Function A Lib "Test.dll" (ByRef field As Variant) As Long ReDim FName(4) As String FName(1) = "1" FName(2) = "22" FName(3) = "333" FName(4) = "4444" Call A(fieldName) C++側は、以下の形で受けているようです。 A(variant *field); SAFEARRAY *psa = *(field->pparray); VB.NET側で以下の様にしてみたのですが、まともに動いてくれません。 Public FName() As String Declare Function A Lib "Test.dll" (ByRef field As Object) As Integer ReDim FName(3) As String FName(0) = "1" FName(1) = "22" FName(2) = "333" FName(3) = "4444" Call A(FName) VB.NETに詳しい方であれば、すごく基本的なことなのではないかと思いますが、よろしくお願いいたします。

  • VBからCで作成されたDLLへの引数の渡し方

    VBからCで作成されたAPI関数への引数の渡し方がわかりません。 C側の引数のデータ型はchar型でポインタ渡しではありません。 ------------------------------------------------ C側 int KANSU(char Mode) VB側 Public Declare Function KANSU Lib "USERAPI.dll" ( ByVal CHAR As Byte) As Long ------------------------------------------------ C側がポインタ渡しの場合は、VB側はSTRING型で別に悩むことはなかったのですが、文字列渡しの場合は、VB側はBYTE型で渡す必要があり、その方法がわかりません。 どなたか、分かる方よろしくお願いします。 ちなみに、VB6.0です。

  • Delphi6でVB.NETで作成のDLL呼出

    VisualSutudio2005で作成され提供されているDLLをDelphi6から呼びだしたいと思っています。 提供ファイルとしてあるのは以下のものです。 ・DLLファイル本体 ・XMLファイル 直接は呼びだせない(?)と思ったので、 VB.NETでDLLを作って間に入れて、 下のように呼び出せばいいのかなと考えています。 Delphi6で作成のEXE → VB.NETで作成のDLL(COM登録?) → 対象のDLL まずはDelphi6のEXE→VB.NETのDLLの部分を作って試してみたですが Delphi6のEXEの起動時にエラーとなってしまいます。 「アプリケーションの初期化に失敗しました」 ネットなどで調べてみて作り方は下記のようにしました。 <呼ばれる側:VB.NETのDLL> 1.COMクラスを作る。   ・COM参照可能の設定にした。 (タイプライブラリが作成され、レジストリへのCOM登録は自動でされる?) 2.作成したDLLはCドライブ直下に置いた。 ※下の*****は自動作成された固定値が入っています。  また見やすくするためここでは半角空白を全角空白に変えています。 -------------------------------------------------------------------- Imports System.Windows.Forms <ComClass(Middle_Dll.ClassId, Middle_Dll.InterfaceId, Middle_Dll.EventsId)> _ Public Class Middle_Dll #Region "COM GUID"   ' これらの GUID は、このクラスおよびその COM インターフェイスの COM ID を   ' 指定します。この値を変更すると、   ' 既存のクライアントはクラスにアクセスできなくなります。   Public Const ClassId As String   = "**************************"   Public Const InterfaceId As String = "**************************"   Public Const EventsId As String  = "**************************" #End Region   ' 作成可能な COM クラスにはパラメータなしの Public Sub New() を指定しなければ   ' なりません。これを行わないと、クラスは COM レジストリに登録されず、   ' CreateObject 経由で   ' 作成できません。   Public Sub New()     MyBase.New()   End Sub   Public Sub DispMsg()     Dim MsgRet As MsgBoxResult     MsgRet = MessageBox.Show("VB.NET DLLより表示!", "確認メッセージ", MessageBoxButtons.YesNo, MessageBoxIcon.Information)   End Sub End Class --------------------------------------------------------------------- <呼び出し側:Delphi6のEXE> 1.タイプライブラリの取り込み設定で登録したDLLを選択し、   「コンポーネントラッパーの作成」にチェックを入れてインストールを実行。 --------------------------------------------------------------------- unit Unit1; interface uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls,OleCtnrs,ComObj, OleServer; type  TForm1 = class(TForm)   Button1: TButton;   Edit1: TEdit;   procedure Button1Click(Sender: TObject);  private   { Private 宣言 }  public   { Public 宣言 }  end; var  Form1: TForm1;  //----------  //静的呼出  //----------  procedure DispMsg();Stdcall; external 'c:\Middle_Dll.dll' name 'DispMsg'; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin  //----------  //静的呼出  //----------  DispMsg(); end; end. ----------------------------------------------------------------- Delphi6のEXEはすでにあるものなので、 呼び出し元はDelphi6から変えられませんが、 呼び出し先はC#やC++でも構いません。 (1)Delphi6のEXE→VB.NETのDLLの呼び出しは可能でしょうか? (2)可能でしたら不具合と思われる箇所はどこでしょうか? (3)この方法より良いと思われる方法はありますでしょうか? DLLを作った事がないので見よう見まねで作っています。 気になる点やアドバイス程度でも構いませんので、 どうかよろしくお願いいたします。 == 開発環境 == WindowsXP SP3 Delphi6 Enterprise SP2 VisualSutudio2005 ProffesionalEdition 評価版 .NET Framework 1.1~3.5

  • VB2008によるOCX作成、またはHTMLからのDLL呼び出しは可能でしょうか?

    こんにちは。 はじめての投稿になります。 私は現在、「ファイルを開く」のコモンダイアログボックスを起動できるHTML画面を作りたいと思っております。 その画面ではサーバ側のファイルを閲覧させたいのですが、認証やセキュリティなどの観点から、 ダイアログボックスの起動はクライアント側で動作するようにしたいです。 それにあたって、ダイアログボックスを呼び出すオブジェクトをAxtiveXコントロール(OCX)で作成し、 そのOCXをHTMLから呼び出すことで実現できないかと考えました。 そこで、以下のことを調べております。 (1)無償のVB開発環境を使ってAxtiveXコントロールを作成することができるか? (2)AxtiveXコントロールを作成できないなら、AxtiveX DLLをHTMLから呼び出せるか? ちなみに現在使用している「無償のVB開発環境」は、Visual Studioの Visual Basic 2008 Express Edition です。 (1)に関しては、VB6ではAxtiveXコントロールを作成できたと聞きますが、どうもVB2008では(.Netでは)作成できないようです。(現在までに見つけた情報に、「.Netで作成できる」というものがないため) (2)に関しては、VB2008 Express Edition を使って、ダイアログボックスを呼び出す AxtiveX DLL を作成することには成功しています。 VBのCOMクラスのテンプレートにダイアログボックス起動の関数を記述し、ビルドしてdllを作成。 ↓ 別途VBによるWindowsフォームアプリケーションを作成し、「参照の追加」で上記dllを登録してダイアログボックス起動の関数を呼び出す。 という方法で、ダイアログボックスを呼び出せました。 ですので、HTMLの画面からも同じようにdll呼び出しができないかと思ったのですが、現在のところ方法が見つかりません。 ダイアログボックスを開く機能さえあればよく、ユーザーインターフェースは不要なので AxtiveX DLL でもよいと思ったのですが、HTMLからの呼び出しにはDLLではなくOCXを用いるという情報しか見つけられませんでした。 以上のことから、VB2008ではHTMLからダイアログボックスを呼び出すActiveXを作れないのではないか?と思える状態なのですが、それが可能であるという話がもしありましたら、お教えいただきたく思います。 最低限「クライアント側からのダイアログボックス起動ができるHTML」「ダイアログボックス起動はVBで作成」という条件を満たせればよいので、(1)(2)で実現できなければ別の方法を探すことにします。 最後に 必要かどうかわかりませんが、(2)で試しに作ったダイアログボックス呼び出しのCOMクラスのソースを載せておきます。 ご回答の参考になりますでしょうか。 Imports System.Windows.Forms <ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _ Public Class ComClass1 Public Const ClassId As String = "2bdd38a4-f946-44e2-af47-5b9cbd2c24d5" Public Const InterfaceId As String = "fcd22890-f4cd-4e2a-b8c0-ae83f290c250" Public Const EventsId As String = "86c74809-966a-47cf-9324-adce776030eb" Public Sub New() MyBase.New() End Sub Public Function subOpenFile(ByVal inFilePass As String) As Boolean subOpenFile = False 'OpenFileDialogクラスのインスタンスを作成 Dim ofd As New OpenFileDialog() If inFilePass = "" Then ofd.InitialDirectory = "C:\" Else ofd.InitialDirectory = inFilePass End If ofd.Filter = "HTMLファイル(*.html;*.htm)|*.html;*.htm|すべてのファイル(*.*)|*.*" ofd.FilterIndex = 2 ofd.Title = "開くファイルを選択してください" ofd.RestoreDirectory = True ofd.CheckFileExists = True ofd.CheckPathExists = True 'ダイアログを表示 If ofd.ShowDialog() = DialogResult.OK Then Console.WriteLine(ofd.FileName) End If subOpenFile = True End Function End Class (呼び出し側では以下の記述で呼び出しに成功しました) Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Test As New COMTest1.ComClass1 Call Test.subOpenFile("C:\WINDOWS") End Sub 以上、よろしくお願いいたします。

  • C++で作成したDLLを vb.net から動的に

    C++で作成したDLLを vb.net から動的に使用する方法 <DllImport("DllNAME")> _ Private Shared Function FuncName( _   <MarshalAs(UnmanagedType.LPStr)> ByVal str1 As StringBuilder, _   <MarshalAs(UnmanagedType.LPStr)> ByVal str2 As StringBuilder ) As String End Function Sub huga()   Dim result As String = FuncName( "hoge", "piyo" )   MsgBox(result) End Sub 上記方法で 静的にはリンク出来たのですが 動的にリンクする方法がわかりません ご教授ください お願いします!

専門家に質問してみよう