- PR -

混在環境でのスタティックな変数へのアクセス

1
投稿者投稿内容
ブラウニー
会議室デビュー日: 2007/05/12
投稿数: 8
投稿日時: 2007-05-17 17:28
お世話になります。

以下のような設計で、C++ CLR C# 混在環境をテストしています。


A:メインとなるプロジェクト スタティックライブラリ C++
  スタティックなメンバ TestId (初期値0) と、スタティックな関数 IncTestId() を持ってる。
  IncTestId() は TestId に1を加えて、TestIdの値を返すだけの関数。

B:UIを担当するプロジェクト exe C#
  CとDを参照している。CとDのIncTestId_1()、IncTestId_2() を実行する。

C:橋渡しをするプロジェクトその1 dll CLR
  Aを参照している。IncTestId()をラップした関数 IncTestId_1() をもつ。

D:橋渡しをするプロジェクトその2 dll CLR
  Aを参照している。IncTestId()をラップした関数 IncTestId_2() をもつ。


この環境で、Bを実行した結果、

IncTestId_1() を実行したときの返り値 1
IncTestId_2() を実行したときの返り値 1

となりました。期待した結果は 1, 2 なのですが、どうしたら期待通りの結果にできるでしょうか?
定石、アドバイスなどよろしくお願いします。

一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-05-17 17:44
Aは.NETのアセンブリじゃないんですね?

Aと.NETの世界の橋渡しをするラッパーを作るというのはどうでしょう。
CとDからはそれを参照するようにします。
ブラウニー
会議室デビュー日: 2007/05/12
投稿数: 8
投稿日時: 2007-05-17 18:09
Aはこんな感じのソースです。

--- A : NexContext.h -------------------

#pragma once

class NexContext
{
public:
static int IncrementId();

private:
static int m_Id;
};

--- A : NexContext.cpp -------------------

#include "NexContext.h"

int NexContext::m_Id = 0;

int NexContext::IncrementId()
{
return ++m_Id;
}

なので.Netのアセンブリじゃないですね。

提案の方法は、これをさらにラップした

E:Aのラッパープロジェクト dll CLR
 C、Dに参照される。

っていうのを作るってことですよね。試してみます!
ブラウニー
会議室デビュー日: 2007/05/12
投稿数: 8
投稿日時: 2007-05-17 18:52
期待通り 1, 2 という結果を得られました!ありがとうございます。

せっかくなので理解しておきたいのですが、CとDのDLLを作成するときに、
スタティックライブラリであるAをリンクしたため、CとDそれぞれにスタティッ
クなメンバができてしまったということなんでしょうか?

またB実行時に、C、Dともにロードされた状態で実行されますが、名前の衝突で
エラーになったりはしないんでしょうか?
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-05-18 11:42
引用:

ブラウニーさんの書き込み (2007-05-17 18:52) より:
CとDのDLLを作成するときに、スタティックライブラリであるAをリンクしたため、CとDそれぞれにスタティックなメンバができてしまったということなんでしょうか?


ネイティブと.NETの共存的な話は私は良く分かりませんが、多分そういうことだと思います。
スタティックリンクライブラリというのは、実行形式のプログラムの中にライブラリの内容そのものを含めてしまうようなリンクの仕方をするんですよね。

引用:

ブラウニーさんの書き込み (2007-05-17 18:52) より:
B実行時に、C、Dともにロードされた状態で実行されますが、名前の衝突で
エラーになったりはしないんでしょうか?


メモリにロードされると最終的にはロードされたアドレスなどで変数や関数を識別するんでしょうから、複数ロードされても区別できるんじゃないでしょうかね。
……すいません、適当なこと言っちゃいました。識者の方書き込みをお願いします。

Aをdllにしたらどうなんでしょうか。Eを作らなくても思ったような動作をしませんかね。
ブラウニー
会議室デビュー日: 2007/05/12
投稿数: 8
投稿日時: 2007-05-22 11:40
>>Aをdllにしたらどうなんでしょうか。Eを作らなくても思ったような動作をしませんかね。

これだといけそうだなーと思ってやってみたんですが、dllにするとCLRのリンク時に、libじゃないとだめです。みたいなエラーになってしまうんですよね。なにか回避方法あるのかも含めて引き続き調べてみます。コメントありがとうございます。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-05-22 15:17
「libじゃないとだめです。」
ってのは、
「'..\debug\xxx.lib' を開くことができません。」
ってやつでしょうか。

dllのプロジェクトを作成する時のウィザードの画面で「シンボルのエクスポート
」というのにチェックをつけて作成してみてください。
すると、勝手に
#define プロジェクト名_API __declspec(dllexport)
こんなdefineが追加されて、これを使った空のクラスが定義されるはずです。
__declspec(dllexport)を使ったクラス(や関数?)が定義されていないとlibが出来ないみたいですね。
これはdllの外から使えるようにするという意味のものなのかな。ちょっと良く分からないですけど。
ウィザードからやり直さなくても自分で__declspec(dllexport)を追加するだけで大丈夫です。
1

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