- PR -

.NET Compact FrameworkでDLLを呼び出す−2

1
投稿者投稿内容
Kei
会議室デビュー日: 2005/09/27
投稿数: 5
投稿日時: 2005-09-27 13:53
みなさん、はじめまして、よろしくお願いします。

eMbedded VC++ 4.0で作成したDLLを
C#のスマートデバイスアプリケーションから呼ぶことが出来ません。
System.MissingMethodExceptionというエラーが表示されます。

過去ログに同じ件名があります。参照元記事URLに入れてあります。
私もあやさんと同じエラーで苦戦しています。
あやさんは解決できたみたいですが、私は、同じようにしても解決できませんでした。
また、あやさんは最初PC上では動作していたとありますが、
私はPC上でも動作していません。
関数名も確認しましたが、問題ありません。

なにか設定とかを変更しないといけないのでしょうか?
サンプルソースを載せますので、ご助言よろしくお願いします。

--- eMbedded Visual C++ 4.0 (WCE Dynamic-Link Library)
Test.h
extern "C" __declspec(dllexport) int GetIntValue();

Test.cpp
extern "C" __declspec(dllexport) int GetIntValue()
{
return 123;
}

--- Visual C# .NET (SmartDeviceApplication)
Test.cs
public class Test
{
[DllImport("Test.dll")]
public static extern int GetIntValue();
}

TestForm.cs
private Init()
{
try{
int val = Test.GetIntValue();
MessageBox.Show(val.ToString());
}
catch(Exception ex){
MessageBox.Show(ex.ToString());
}
}
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-09-27 14:25
引用:

eMbedded VC++ 4.0で作成したDLLを
C#のスマートデバイスアプリケーションから呼ぶことが出来ません。
System.MissingMethodExceptionというエラーが表示されます。



エラーの原因は、DLL を dumpbin.exe ユーティリティで DLL 関数のエクスポート名を確認してみればすぐに分かります。

__declspec 修飾子を使用しただけだと、DLL 関数のエクスポート名は _hoge@4 などのように引数の長さを表す文字列が付加されるのです。

DLL のプロジェクトに.def ファイルを追加して DLL 関数のエクスポート名を明示的に指定すれば解決します。
Kei
会議室デビュー日: 2005/09/27
投稿数: 5
投稿日時: 2005-09-27 14:59
渋木さん、ありがとうございます。

今確認してみました。結果を抜粋すると

ordinal hint RVA name

1 0 00001024 GetIntValue

となっていました。
これは、DLL関数のエクスポート名はGetIntValueで
問題ないように思えます。

コマンドラインからは、

dumpbin.exe /EXPORTS "Test.dll"

としました。間違っていたらご指摘ください。
また、他に何か原因は考えられないでしょうか?
よろしくお願いします。

[ メッセージ編集済み 編集者: Kei 編集日時 2005-09-27 15:04 ]
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-09-27 18:49
こんにちは。

Compact Framework は触った事有りません^^;なので、アドバイスになりませんが。

普通の Framework で、DLL は見つかったが、関数が見当たらない時
EntryPointNotFoundException
という例外が出ます。(MissingMethodException ではない。)
何で違うのでしょう。
Compact Framework はそういう例外を出すって言うのかな。
何かヒントになりませんか?
Kei
会議室デビュー日: 2005/09/27
投稿数: 5
投稿日時: 2005-09-27 19:11
囚人さん、ありごとうございます。

今、EntryPointを入れてして実行してみました。
結果は変わらず、MissingMethodExceptionが表示されます。

他にも何かありましたら、よろしくお願いします。

Kei
会議室デビュー日: 2005/09/27
投稿数: 5
投稿日時: 2005-09-28 19:15
一応、解決できました。

ポケットPCは、デバイス本体のWindowsフォルダしか見にいかないらしく
ここに自分で作成したDLL(今回だとTest.dll)をコピーしておく必要が
あるみたいです。
実際、コピーして実行したらうまく動作しました。
しかし、エミュレータではうまく動作していません。
こちらも、どこかにコピーする必要があるのかもしれません。
とりあえず、デバイスで動作するようになったので報告しておきます。
また、他の解決方法がわかったときは報告します。
Kei
会議室デビュー日: 2005/09/27
投稿数: 5
投稿日時: 2005-09-30 18:26
追加情報です。

あいかわらず、デバイス上でしか動作していませんが、
新たな情報を報告いたします。
想像できることですけど、念のために報告します。

前回、スマートデバイスアプリからVC++のDLLを呼び出す場合、Windowsフォルダにコピーすれば動作すると報告しました。

更に、WindowsフォルダにコピーしたDLLが他のDLLを呼んでいる場合は、そのDLLも同様にコピーしておかないといけないことがわかりました。これは、直接アプリから呼び出していなくてもです。

また、何かわかりましたら報告いたします。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-10-04 00:17
引用:

前回、スマートデバイスアプリからVC++のDLLを呼び出す場合、Windowsフォルダにコピーすれば動作すると報告しました。



プラットフォームのバージョンや構成によります。
相当古い Pocket PC を使ってませんか?

引用:

更に、WindowsフォルダにコピーしたDLLが他のDLLを呼んでいる場合は、そのDLLも同様にコピーしておかないといけないことがわかりました。これは、直接アプリから呼び出していなくてもです。



DLL が Windows フォルダからしか読み込まれないのであれば当たり前の話ですね。
1

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