- PR -

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

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



引用:


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

DLLの関数の戻り値を構造体にすることは、普通に可能ですけどねぇ・・・

たとえば、

コード:
DLL側

typedef struct TESTSTRUCT
{
	int a;
	int b;
} stTest;


stTest GetSTData()
{
	stTest dat;

	dat.a = 1;
	dat.b = 2;

	return dat;
}



コード:
 
DLL呼び出し側

stTest mydat;
mydat = GetSTData();





自分もこういう風にやったつもりだったのですが…(−−;)

DLL側がC#だから?っていうこともないですよねぇ。
「VC++5.0」との差なんて。。。



「 LIBファイル」の検証はもう少しお待ちください。
また後で書込みします。
りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-19 12:02
引用:

自分もこういう風にやったつもりだったのですが…(−−;)

DLL側がC#だから?っていうこともないですよねぇ。
「VC++5.0」との差なんて。。。



な、なるほど。ぼくがどの環境で例を作成したか、書いておりませんでした・・・^^;
申し訳ありませんでした。
DLLも、DLLを呼び出す方も、VC++6.0です。VC++5.0であれば、大差ないと思います。
ちなみに、DLLのプロジェクトはどれ使ってます?
MFCのやつとか、いろいろできるんですが、作り方がまったく違う事は無いですが、
ぼくは、「Win32 Dynamic-Link Library」のプロジェクトです。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2004-02-19 13:46
ども、ほむらです。
やっぱり見当違いだったようですね。
失礼しました。
--------
細かい部分はさておいて、構造体の代入ってデフォルトでできたんですね^^;;;
いつもmemcpy()?使ってました。

ゆうじゅん氏とりばぁ氏、お二方にフォロー感謝です^^

ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2004-02-19 14:11
引用:

細かい部分はさておいて、構造体の代入ってデフォルトでできたんですね^^;;;
いつもmemcpy()?使ってました。




実を言うとわたしも代入できるとわかったのは最近のことでした^^;
なのでC言語の場合はmemcpyをC++になってからはメンバそれぞれを1個づつ代入してました

C言語のときは構造体をBYTE配列を任意の型で仕切っているイメージがあったのでmemcpyを
使っていたのですがC++でCStringを構造体に入れるようになってからはmemcpyは
危ないなと思ってメンバそれぞれを代入するようにしてました。


りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-19 14:16
こんにちわ。

引用:

ゆうじゅんさんの書き込み (2004-02-19 14:11) より:
引用:

細かい部分はさておいて、構造体の代入ってデフォルトでできたんですね^^;;;
いつもmemcpy()?使ってました。




実を言うとわたしも代入できるとわかったのは最近のことでした^^;
なのでC言語の場合はmemcpyをC++になってからはメンバそれぞれを1個づつ代入してました

C言語のときは構造体をBYTE配列を任意の型で仕切っているイメージがあったのでmemcpyを
使っていたのですがC++でCStringを構造体に入れるようになってからはmemcpyは
危ないなと思ってメンバそれぞれを代入するようにしてました。




 むむ、なるほど、そういう問題を気にされていたのですね。
昔のANSI Cの規格では、構造体の直接代入は認められていませんでしたね。
(いつからおっけーになったかは知りません^^;)

memcpyで構造体のコピーをすることは、サイズをsizeofでちゃんと取れば、
問題は無いと思います。構造体は、アライメントの問題もありますから。

[ メッセージ編集済み 編集者: りばぁ 編集日時 2004-02-19 14:21 ]
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-19 20:11
優希です。


引用:

DLLも、DLLを呼び出す方も、VC++6.0です。VC++5.0であれば、大差ないと思います。
ちなみに、DLLのプロジェクトはどれ使ってます?
MFCのやつとか、いろいろできるんですが、作り方がまったく違う事は無いですが、
ぼくは、「Win32 Dynamic-Link Library」のプロジェクトです。



すいません。
今、手元に確認できる環境がないので、
「Lib」関係も含めて、
明日、朝一で確認して、報告させてもらいます。

宜しくお願い致します。
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-21 13:41
優希です。

返事が遅くなってすいませんでした。m(_ _)m
早速、いろいろ試してみました。

引用:


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

LIBファイルをLIBフォルダから削除してみたらエラーが変わります?
「LIBファイルが見つかりません」とかに



上記の処理をして見ましたが、
予想通り、エラーが変わりました。
引用:

LNK1104 コンパイルは、ファイル 'Sample.lib' を開くことができません。


…っていうことは。。。

VC5で呼び出しできるか試してみたのですが、
同じく「外部参照が未解決」ってなってしまいました。
自分の呼び出し側のつくりが正しくないのか、
LIBファイルが良くないのか、ですねぇ(^^;)


それと、
引用:


りばぁさんの書き込み (2004-02-19 12:02) より:

ちなみに、DLLのプロジェクトはどれ使ってます?
MFCのやつとか、いろいろできるんですが、作り方がまったく違う事は無いですが、
ぼくは、「Win32 Dynamic-Link Library」のプロジェクトです。



すいません。
「VC++4.0」を使っておりました。。。
DLLは、りばぁさん同様、「Dynamic-Link Library」のプロジェクトで
作成しております。

うーん、もっと簡単にできると思ったのに。。。
もう少し、考えてみます。
りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-23 10:50
こんにちわ。

VC++4.0ですか・・。ま、まぁDLL作成するのには影響は無いとおもいます。
(もしかすると規格が古くて構造体を戻り値にすることが出来ない可能性はありますね。
投稿日時: 2004-02-19 14:16より)

エラーに関しては、ヴァージョンなどの問題では無さそうです。
DEFファイルはちゃんとされているようなので、関数の宣言や定義自体に
問題があるかもしれません。

僕自身、DLLの作成は、決まりごと(?)に沿って盲目的に作っちゃったりするので
正確ではないことも言ってしまうかもしれませんが。^^;

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

コード:
stTest __stdcall GetSTData()
{
	stTest dat;

	dat.a = 1;
	dat.b = 2;

	return dat;
}



と言う感じで。

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

あと、まぁVC++で作成しているので、該当しないとは思いますが、DLL関数をC言語(C++ではなく)
で作成している場合は、

ヘッダーファイルに

コード:
#ifdef __cplusplus
extern "C" { 
              
#endif

stTest __stdcall GetSTData()

#ifdef __cplusplus
}
#endif




とかなっていないとダメかもしれません。(プロジェクト作成時に自動的に出来ているかも)

気づくのは大体このあたりですが。

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

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