- PR -

DLL内の関数の戻り値を構造体で受け取るには…。

投稿者投稿内容
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-23 23:42
りばぁさん、ありがとうございます。

引用:

もーすこし単純なところから考えると、
LIBファイルとDLLファイルのバージョンはあっていますか?コピーし忘れとかで
どちらかが古いと怒られると思います・・・。


そうなんですよねぇ。
ここら辺も、いろいろ確認してみたんですけど、
ダメでした。。。

他にりばぁさんがアドバイスしてくれたことを
もう少し試してみたいと思います。

・・・うーん、難しい。。。
もぐ
会議室デビュー日: 2002/12/06
投稿数: 13
投稿日時: 2004-02-24 00:55
はじめまして、かなり遅いレスですが...

引用:

優希さんの書き込み (2004-02-19 09:33) より:

引用:

LNK2001: 外部シンボル""SampleMethod()"(?SampleMethod@@$$FYGFEEFJPAD@Z)"は未解決です。
LNK1120: 外部参照1が未解決です。





って事ですので、SampleMethod()が入っているDLLの作成時と、
呼び出すTestMethod()が入っているEXEの作成時で、コンパイラが
作成する関数名の違いがないでしょうか?

1.DLLとEXEを作成しているコンパイラが違う
2.DLLは.cでEXEは.cppで記述している
3.コンパイラオプションが異なっていて呼び出し方式が異なる
4.そもそもDLL側で対象関数をエクスポートしていない

等が考えられます。

次のコードで試せないでしょうか?
Sample.h
コード:
#ifdef __cplusplus
extern "C" {
#endif

#ifdef SAMPLE_IMPLEMENT
#define	DLLDECLARE __declspec(dllexport)
#else
#define	DLLDECLARE __declspec(dllimport)
#endif

DLLDECLARE void __stdcall SampleMethod();

#ifdef __cplusplus
}
#endif



SampleDLL.cpp
コード:
#include <stdio.h>
#define SAMPLE_IMPLEMENT
#include "Sample.h"

DLLDECLARE void __stdcall SampleMethod(){
	puts( "SampleMethod" );
}



SampleEXE.cpp
コード:
#include "Sample.h"

#pragma comment( lib, "SampleDLL.lib" )

void main(void){
	SampleMethod();
}

ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2004-02-24 10:26
的はずれだったら申し訳ないのですが
defファイルのEXPORT部分の「@1」、「@2」を削ってみたらどうでしょうか?
昔似たようなことではまった記憶が・・・・
おそらく

SampleMethod()"(?SampleMethod@@$$FYGFEEFJPAD@Z)というEXPROT情報が
受け取る側の仕様とあっていないということだったはずです。

どうやって解決したかはいま思い出していますので、なにか思い出したら書き込みします。
あやふやで申し訳ありません
りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-24 10:54
引用:

ゆうじゅんさんの書き込み (2004-02-24 10:26) より:
的はずれだったら申し訳ないのですが
defファイルのEXPORT部分の「@1」、「@2」を削ってみたらどうでしょうか?
昔似たようなことではまった記憶が・・・・
おそらく



これは意外と有効かもしれませんね。
序数値はなくても構いませんし。というか、ぼくはいつもつけていません^^;

ところで、初心(?)にいきなり帰りますが、優希さんの最初の書き込みで、
引用:

呼び出すDLL内の関数の引数に構造体を設定すると、
きちんと設定することができます。


この場合は、ちゃんとDLLの関数を呼び出すことが出来ているんですよね?
ということは、DLLの作り方そのものは問題ない気がします・・・。
たとえば、戻り値に使用しようとしている構造体のメンバー変数に、アヤしい型(?)が
まじってたりしませんか?(動的にメモリ確保して扱うようなものとか・・・)

と、いろいろ疑わしいことを挙げてもキリがないのですが、一番はやはり、
VC++4.0であるということ・・・。
可能であれば、VC++.NETでリビルドして使用できませんかねぇ?

VCは、ANSI規格に沿っている部分とMicrosoft独自の部分とある上に、規格が古そうなのが
気になります・・。そのあたりに詳しい方はいらっしゃいませんかねぇ^^;
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-25 16:38
優希です。
レスが遅くなってすいません。


引用:

りばぁさんの書き込み (2004-02-23 10:50) より:

まず、関数の定義に ”__stdcall”をつけてなければ、つけてみてください。
ぼくが以前例に出したコードではつけていないのですが^^;



自分もこれはつけていたので、
問題なさそうです。


引用:

りばぁさんの書き込み (2004-02-23 10:50) より:

また、DLL作成方法として、DEFファイルを使用する以外に、”__declspec(dllexport)”
キーワードを使用することも出来ます。これはたぶん両方あったりすると怒られるかも。



↑の書込みで思ったのですが、
今回の例では、分かりやすくひとつの関数の呼び出しをやっておりますが、
実際はたくさん関数もあり、呼び出し先のDLLから別のDLLも呼び出しておりました。
(すいません。結構、重要なことだったかも…)

A(呼び出し元)⇒B.dll(VC++4.0)⇒C.dll(VC++4.0)

という具合にです。


もぐさんのサンプル(投稿日時: 2004-02-24 00:55)や、
自分が書いたサンプルをやってみるとLIBファイルを使っての
DLL呼び出しが出来ました!
(誠に申し訳ないですm(_ _)m)


それで、本題ですが、
この「B.dll」のヘッダファイル内で、
コード:
__declspec( dllimport ) void SetValue(int value);


などとC.dllの関数をインポートしていると、
A(呼び出し元)でLIBファイルを使って、
呼び出すことは出来ない!ってことはないですよね!?
…全く別の問題だと思いますが。。。念のため


あと、
引用:

ゆうじゅんさんの書き込み (2004-02-24 10:26) より:

defファイルのEXPORT部分の「@1」、「@2」を削ってみたらどうでしょうか?
昔似たようなことではまった記憶が・・・・


も試してみたのですが、
同じでエラーのままでした。。。


---
構造体の受け渡しの件ですが、
りばぁさんのいうような難しい型などは
使っていないのですけどねぇ〜(^^;)
(BYTE型やLPSTR型など)

もうちょっとシンプルなサンプルを作って
試してみます。


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