- PR -

ネイティブコードのDLLへの参照渡しの方法(文字列型)

投稿者投稿内容
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2004-02-10 00:52
こんばんは、meiです。

引用:

優希さんの書き込み (2004-02-09 19:25) より:
# ちなみに、Sample.dllの内容は、
# 変更したくないので、呼び出し側で
# 対応できたら、、と思っています。



ちょっとした疑問なのですが、C++を使っているのでしたら、
そのままUnmanagedコードを呼び出せないのでしょうか?

コード:

// Sample.dllのlibをリンク
#pragma comment(lib, "Sample.lib")

// 関数の宣言
// もし、ヘッダがあれば、そっちをインクルード
extern "C" short GetData(long NumValue, LPSTR data1, LPSTR data2);

int _tmain()
{
char buf1 [32];
char buf2 [32];
// 取りあえずUnmanaged関数をそのまま呼ぶ
GetData(10, buf1, buf2);
// 必要に応じてString型へ
String* s1 = new String(buf1);
String* s2 = new String(buf2);
return 0;
}



何らかの理由でDllImportを使用しているのでしたら済みません。

あ、yaさんとかぶってしまった(汗)


[ メッセージ編集済み 編集者: mei 編集日時 2004-02-10 00:54 ]
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-10 10:04
優希です。

yaさん、meiさん、
有難う御座います。

引用:

yaさんの書き込み (2004-02-10 00:08) より:

追記:単純な疑問ですが、MC++使うのならば普通に
libファイルやLoadLibraryでリンクすればいいように思うんですけど、
なんか事情があるんですか?


引用:

meiさんの書き込み (2004-02-10 00:52) より:

ちょっとした疑問なのですが、C++を使っているのでしたら、
そのままUnmanagedコードを呼び出せないのでしょうか?



いいえ、特には事情もないんですけど、
以前、INIファイルの読込み関数を

コード:
// Win32API Iniファイル読込み
[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringA")]
static long GetPrivateProfileString(String *lpAppName, 
                                    String *lpKeyName,
                                    String *lpDefault, 
                                    StringBuilder *lpReturnedString,
                                    long nSize, 
                                    String *lpFileName);



・・・とやって出来ていたものですから、
同じようにやってみたのですが。。。



引用:

yaさんの書き込み (2004-02-10 00:08) より:

今簡単に実験してみましたけど、StringBuilderでいけましたよ。



そうですかぁ。
Sample.dllにメッセージボックスを出力するようにしてみたのですが、
どうも呼ばれていないらしいです(−−;)
ちょっと早とちりし過ぎたかも。。
すいません。


でも、同じように乱数を取得する関数を別DLLで作ってみたのですが、
きちんと値が返ってきて(return文で・・・)いるんですよねぇ。

コード:
///
/// 乱数取得関数
///
NOMANGLE int CCONV GetRandValue()
{
	int randValue;

	// 実行するたびに違う値が得られるように、現在の時刻値を使って
	// 乱数ジェネレータを初期化します。
	//
	srand( (unsigned)time( NULL ) );
	randValue = rand()%100;
	return randValue;
}





ちなみに、引数の型の対応(ネイティブコード ⇒ マネージドコード)は
正しいですよね?(VC++.netで)
-------------------------
BYTE ⇒ BYTE
short ⇒ int
long ⇒ long
LPSTR ⇒ StringBuilder
-------------------------


もうちょっと、考えてみます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-10 10:11
関係ないですが。。。
引用:

優希さんの書き込み (2004-02-10 10:04) より:

コード:
	// 実行するたびに違う値が得られるように、現在の時刻値を使って
	// 乱数ジェネレータを初期化します。
	//
	srand( (unsigned)time( NULL ) );




これって、起動時に一回呼んでおけばよいのでは?毎回呼ぶ必要はなかったと思う。
ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2004-02-10 10:22
C++の参照渡しなら

static int GetData(long NumValue, String *strData1, String *strData1);

static int GetData(long NumValue, String &strData1, String &strData1);

String *strData1;
String *strData2;

String strData1;
String strData2;

でできると思います

(追加)
よくよく見てみたら全然的外れな答えでしたね。最初の説明をよく読んでない証拠です。
申し訳ない

[ メッセージ編集済み 編集者: ゆうじゅん 編集日時 2004-02-10 11:29 ]
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-02-10 10:44
優希です。

引用:

Jittaさんの書き込み (2004-02-10 10:11) より:

これって、起動時に一回呼んでおけばよいのでは?毎回呼ぶ必要はなかったと思う。



そうなんですか、
そのように処理を修正してみます。



引用:

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

C++の参照渡しなら

static int GetData(long NumValue, String *strData1, String *strData1);

static int GetData(long NumValue, String &strData1, String &strData1);

String *strData1;
String *strData2;

String strData1;
String strData2;

でできると思います



うーん、
System.Stringの使い方がおかしいって言われますねぇ。
やはり、「String *strData1; 」と"*"は付けないとダメなような。。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2004-02-10 11:07
引用:
ちなみに、引数の型の対応(ネイティブコード ⇒ マネージドコード)は
正しいですよね?(VC++.netで)
-------------------------
BYTE ⇒ BYTE
short ⇒ int
long ⇒ long
LPSTR ⇒ StringBuilder
-------------------------



http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconplatforminvokedatatypes.asp

ここに対応表があります。
C++の場合short, int, longは実装系依存ですが、Win32 x86のMSコンパイラの場合、
short -> 16ビット
int  -> 32ビット
long -> 32ビット
となってます。
なので、対応表は
-------------------------
BYTE ⇒ System.Byte
short ⇒ System.Int16
long ⇒ System.Int32
LPSTR ⇒ StringBuilder
-------------------------
となると思うんですけど…。
りばぁ
大ベテラン
会議室デビュー日: 2003/11/26
投稿数: 130
お住まい・勤務地: 愛知県
投稿日時: 2004-02-10 11:07
こんにちわ。

[quote]
String *strData1;
String *strData2;
[/qoute]

.NETのメモリ管理とかいまだに良く分からないのでいいかげんなことを
言ってしまうかもしれませんが^^;

ポインタの宣言はありますが、実体が無くて値を受け取る事が出来るのですか??

ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2004-02-10 11:28
と、今気づいた。

引用:

いいえ、特には事情もないんですけど、



それなら普通にネイティブにリンクするほうが自然ですし、何のためのMC++ですかってなっちゃいますよ。
meiさんがやり方は書いてくれているのでその手順でやりましょう。

引用:
以前、INIファイルの読込み関数を

コード:
// Win32API Iniファイル読込み
[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringA")]
static long GetPrivateProfileString(String *lpAppName, 
                                    String *lpKeyName,
                                    String *lpDefault, 
                                    StringBuilder *lpReturnedString,
                                    long nSize, 
                                    String *lpFileName);


・・・とやって出来ていたものですから、
同じようにやってみたのですが。。。


というより、kernel32.dllの関数なんて、自分で宣言は一切追加せず呼べますよ…。

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