
/**** Cプログラム *****/
int testAP( char* a)
aのポインタにアドレスを返します。
/**** VB プログラム****/
Public Declare Function testAP Lib "test.dll" (ByRef a As String) As Integer
Dim keydata As String * 128
lngRc = testAP(keydata)
上記VBのAPを実行するとアプリケーションエラーになります。
Cプログラムのデバックをすると入口ではaのポインタにはアドレスがセットされていて
、値を設定出来、最後まで正常動作して、VBとのインタフェースで落ちています。
VB6.exeでアプリケーションエラーになっています。
恐らく、VBにはポインタという概念が無いと聞いていてCのAPとの受け渡しに失敗して
そうなのですが、VBでの引き渡し方法が分かりません。
よろしくお願い致します。
No.9ベストアンサー
- 回答日時:
>__declspec(dllexport) int testAP(BSTR* cp_KeyData){
>
>→char*からBSTR*に変更しました。
だめです。そんな強引なことをしないでください。
char *でかまいません。
BSTR*にするとメモリ破壊が起きます。
__stdcallはどうしたんですか?
(ごめんなさい、アンダースコア2つですね)
>只、VCのデバックを行うと実行時エラー'49'
>DLLが正しく呼び出せません。が出力される。
>(DLL関数を呼んで処理が終了してVBに戻る所で出力されます。
VBのDeclareステートメントと、Cの処理があっていません。メモリを破壊しているのでしょう。
EXEにして動くのはたまたまでしょう。
この回答への補足
ご指導ありがとうございます。
__stdcallを試してみたのですが、実行時に
実行時エラー'453'
TestAPがDLLファイル C:\bin\test.dll内に見つかりません。
というエラーになってしまいます。
C側は
__declspec(dllexport) long __stdcall testAP(char*)
VB側は
Public Declare Function testAP Lib "c:\bin\test.dll" (ByVal lpKeyData As String)As Long
です。
test.dllはパス通りの場所には置いてあります。
なにか誤りがありましたらご指導お願い致します。
No.10
- 回答日時:
モジュール定義ファイルはDLL作成時に作ってますか?
(ファイル名:test.def)
LIBRARY DLL名
EXPORTS
関数名1
関数名2
関数名3
こんな感じのファイルです。
参考URL:http://lion.zero.ad.jp/~zar70041/zarchis/archive …
この回答への補足
モジュール定義ファイルを作成したところ正常に動作しました。
皆様のご指導の結果、現状
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に値を設定する
}
モジュール定義
--- test.defファイル ----
LIBRARY test
EXPORTS
testAP
上記設定及びコンパイルで実行した結果
VB側でDLLのtestAPを呼び、正常に戻り、keydata変数には
C側で設定した値が返却されました。
VBからCのDLLを呼ぶ際は、モジュール定義ファイルも必要なのですね。
momoturboさん、hayahayahayaさん、taka_tetsuさん、sha-girlさん、FlossenEngelさん
ありがとうございました。皆様のおかげですごく助かりました。
また特にtaka_tetsuさん、sha-girlさんには大変時間をさいてもらって感謝しています。ありがとうございました。
No.8
- 回答日時:
>エントリtestAPがDLLファイル内に見つかりませんと言うメッセージが出力されます。
#7の方の参考urlに書いてある、defファイルを作成してDLLのプロジェクトに追加してビルドしなおしてください。
この回答への補足
皆さんの意見を参考に下記の方法(但し、VBをコンパイル(EXE)にして)で
正しく処理が出来ました。!!
でも、下記の方法で大丈夫なのか不安です。
何かご指摘がありましたら、教えてください。
また、デバック時のエラーについて、知っている方がいれば教えてください。
/* ---- C側のプログラム ------*/
__declspec(dllexport) int testAP(BSTR* cp_KeyData){
→char*からBSTR*に変更しました。
char c_DATA[5]="1234"
LPSTR lp_DATA;
lp_DATA=(LPSTR)cp_KeyData;→LPSTRにアドレスをかぶせる
strcpy(lp_DATA,c_DATA);
return(OK);
}
/* ---- VB側のプログラム ------*/
Public Declare Function testAP Lib "test.dll" (ByVal lpKeyData As String) As Long
Dim lngRc As Integer
Dim keydata As String * 128→128Byte確保、確保しないとエラーとなってしまう?
lngRc = testAP(keydata)→keydataには"1234"が返されました。
/*****************************************************************************/
只、VCのデバックを行うと実行時エラー'49'
DLLが正しく呼び出せません。が出力される。
(DLL関数を呼んで処理が終了してVBに戻る所で出力されます。
VBをコンパイル(EXE)にして実行すると正しく処理が行われるます。
どうしてなのでしょう?
No.7
- 回答日時:
No.6
- 回答日時:
>__declspec(dllexport) int FAR testAP(char* a)
>
>呼び出しは出来るのですが、aのアドレスがNULLです。
かも知れませんね。
呼び出しが出来るかどうかは関数がエクスポートされているかどうかだけです。
で、呼び出し規約は引数の渡し方の定義です。
ちなみに、FARはWin32では意味がありません。
>→ int _stdcall testAP(char* a)に修正した方が
>いいのでしょうか?
__declspec(dllexport) int _stdcall testAP(char* a)
こうしてください。
この回答への補足
度々すみません。
__declspec(dllexport) int _stdcall testAP(char* a)に変更したのですが、エントリtestAPがDLLファイル内に見つかりませんと言うメッセージが出力されます。
ご指摘がありましたらお願い致します。
No.5
- 回答日時:
よくよく見ると
>int testAP( char* a)
呼び出し規約が無いですが平気ですか?。
VBから呼び出す場合は_stdcall規約です。
int _stdcall testAP( char* a)
とか
int WINAPI testAP( char* a)
になるはずです。
>Public Declare Function testAP Lib "test.dll" (ByVal keydata As String) As Integer
戻り値の型がIntegerになってます。
C側ではintなので、32bitですからLongにする必要があります。
で、あとは#4の方の指摘どおり、StrPtrが不要です。
#WindowsAPIの呼び出しってしたこと無いですか?
この回答への補足
すみません、C側は以下の記述を行ってDLLを作成してます。
__declspec(dllexport) int FAR testAP(char* a)
呼び出しは出来るのですが、aのアドレスがNULLです。
→ int _stdcall testAP(char* a)に修正した方が
いいのでしょうか?
ご指摘がありましたら、お願い致します。
No.4
- 回答日時:
StringはByValで渡してください。
またStrPtrが不要です。
lngRc = testAP(keydata)
VB6では内部文字コードはUNICODEで保持しています。
一方CはSJISです。
StringをByValで渡すのは特別な意味があります。
暗黙的に一度SJISに変換してDLLに渡しています。
ByValといっても実際は参照渡しのようなもので
dll側で書き換えた文字列は
keydataに反映されます。
この回答への補足
ありがとうございます。
StrPtrを省略してデバックで検証したのですが、
DLL関数の受け側のポインタがNULLで設定されるため、
渡すことができません。。。
ご指摘通りにStringはByValにして、StrPtrを省略したのですが。。。まだ漏れている点がございましたらご指摘ください。
No.3
- 回答日時:
>Public Declare Function testAP Lib "test.dll" (ByRef a As String) As Integer
正しくはByValです。
http://homepage2.nifty.com/newton/vbe/not_teach/ …
>/**** Cプログラム *****/
>int testAP( char* a)
>aのポインタにアドレスを返します。
ちなみにこれではポインタは返せませんよ。
ポインタの指す領域に文字列は返せますが。
本当にアドレスの値を返したいのであれば、
Win32であればポインタは32ビットなのでLongを使うことになります。
この回答への補足
ありがとうございます。
ご指摘通りポインタを指す領域に文字列も返します。
#1,2,3の方がのご指摘通りに、修正して行ったのですが、
今度は実行時エラー49 DLLが呼び出せませんと出力されすます。
このメッセージはVBからDLL関数を呼んで、関数を抜けて
VBに戻るときに出力されます。
VBの修正は以下の通りなのですが、誤りとあったらご指導お願い致します。
Public Declare Function testAP Lib "test.dll" (ByVal keydata As String) As Integer
Dim keydata As String * 128
lngRc = testAP(StrPtr(keydata))
No.2
- 回答日時:
#1の方と同じですが、
VB6ならstrPtrが使えますが、.Netでは確認していません。
ret = testAP(strPtr(keydata))
で keydata をみてみてください。
No.1
- 回答日時:
まったく自信ありません。
(^ ^;1)strPtrを使用する(文字列のポインタを返します)
lngRc = testAP(strPtr(keydata))
ただし、strPtrは非公式関数みたいです。
.Netではなくなった?
2)Cのdefファイルの設定ミス
インタープリンター場で動かすと、アプリケーション
エラーで落ちますが、VBをexeにしたら落ちなかった
ことがあります。
何をどうすればと、きかれてもわかりません。
Cはよくわからないもので・・
参考になれば幸いです
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ExcelVBAでのkernel32(64bit)
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
参照型で受け取った引数をポイ...
-
セグメントエラー
-
VC++6.0 MFC ダイアログバーを...
-
メモリのアドレスからの値の取...
-
戻り値で構造体を返すことは可...
-
C言語のポインタに直接アドレス...
-
ハンドルはポインタか
-
c言語で任意のファイルから読み...
-
自作関数の引数
-
別のDLLのダイアログを・・・
-
CImage GetBitsメソッドについて
-
リトルエンディアンというもの...
-
CWnd::EnableWindow()の扱い方
-
fopne で失敗する原因
-
ポインタについて
-
Cで作成したDLL関数をVBから呼...
-
nullポインタを逆参照とは?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
セグメントエラー
-
Run-Time Check Failure #3とい...
-
ExcelVBAでのkernel32(64bit)
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
参照型で受け取った引数をポイ...
-
トリプルポインタが必須!とな...
-
ハンドルはポインタか
-
LPSTR型の初期化について
-
ポインターの使用法や利点
-
ポインタについて
-
c言語で任意のファイルから読み...
-
基本アルゴリズムの『返す』の...
-
コンストラクタでnewを失敗した...
-
ハンドル、アドレス、ポインタ...
-
アプリを32bitから64bit移行
-
デバイスハンドルとは?
-
NULLとブランクの違い
おすすめ情報