C++で作ったDLLをC#で使うには?

回答受付中の質問

C++で作ったDLLをC#で使うには?

C#でC++で書いたDLLを使いたいと思っていますが、可能でしょうか?
本で調べてみると出来ると思って挑戦しています。

public class Form1 : System.Windows.Forms.Form
{
[DllImport("test.dll")]
public static extern long abc();
.....
と宣言し、使う時には
long a = abc();
としています。

しかし、いざデバッグして実行してみると、エントリポイントが見つかりません。と表示されてしまいます。

(そもそもDLLが使えるのならばですが)できればC#でC++のDLLが使いたいため、詳しい方ご教授願います。

投稿日時 - 2003-06-17 00:51:08

QNo.577129

困ってます

4人が「このQ&Aが役に立った」と投票しています

[  前へ  |  次へ ]

回答(3件中 1~3件目)

ANo.3

>他に手続きは必要なのでしょうか?

一応こんな感じです。

extern "C" {
__declspec(dllexport) int Test(int x, int y) { return 0; }
}

関数を上のように定義すると "Test" の名前でエクスポートされます。
__cdecl で問題なければ、このエクスポートの方法がいいでしょう。

extern "C" {
__declspec(dllexport) int __stdcall Test(int x, int y) { return 0; }
}

上のように __stdcall を追加すると、今度は "_Test@8" の名前でエクスポートされます。
@以降は、引数に使用するスタックのサイズだったはずです。
このような名前が嫌いで、__stdcall でないと困る場合はDEFファイルを作ります。

---- project.def ----
LIBRARY project
EXPORTS
Test
---------------------
※↑のTestの前にタブかスペースを入れてください

extern "C" {
int __stdcall Test(int x, int y) { return 0; }
}

プロジェクトのプロパティから、リンカ→入力→モジュール定義ファイル と移動し、project.def と入力して OK します。
project.def の名前は自由です。その中のLIBRARY以降の名前は、作成されるDLLと同じ名前にします。
ビルドすると、"Test" の名前でエクスポートされます。

※説明の為に __stdcall と書きましたが、WINAPI と書いた方がいいと思います。

投稿日時 - 2003-06-19 01:10:01

ANo.2

C#のlongは64ビットで、VC++のlongは32ビットなので、C#からはintと扱って問題ないでしょう。

stringはデフォルトでマルチバイトで渡されるので、それで問題なければそのまま渡せます。

C#のlong,float,doubleは渡した事がなかったりもしますが、C#のlongをVC++の__int64と受け取る以外はそのままいけそうな気がします(役にたたずすいません)。

投稿日時 - 2003-06-17 20:04:59

補足

その後色々と試した結果、過去に作ったDLLは読めるようになってきたのですが、新しく作っているものが読めません。
もしかしたらDLLの作成方法に問題があるのかもしれません。

現在、win32プロジェクトからDLLを作成しています。
例えば、足し算をする関数を作る場合、test.hには
TEST_API int __stdcall Tasizan(int a,int b);
とし、test.cppには

TEST_API int __stdcall Tasizan(int a,int b)
{
int ans;
ans = a + b;
return ans;
}

としてDLLを作っています。
しかし、これだと前述のようにエントリポイントが見つかりませんとなってしまいます。

他に手続きは必要なのでしょうか?
初心者の質問で本当にすみません。

投稿日時 - 2003-06-18 19:27:56

お礼

色々と勉強になりました。
変数のビット数を考慮する必要があるのですね。
これから、色々と試してみたいと思います。

どうもありがとうございました!

投稿日時 - 2003-06-18 14:29:31

ANo.1

DLLが使えるのは間違いないです。

[DllImport("USER32.DLL", EntryPoint="MessageBoxW")]
private static extern bool MBox(
int h,
[MarshalAs(UnmanagedType.LPWStr)] string m,
[MarshalAs(UnmanagedType.LPWStr)] string c,
int type);

MBox(0, "文字列", "タイトル", 0);


あとは、DLLのエントリーポイント名が本当にabcなのかってところでしょう。
私はコマンドラインから、dumpbin /EXPORTS test.dll と確認しています。

投稿日時 - 2003-06-17 03:20:06

お礼

ありがとうございます。
試行錯誤した結果、動作するようになりました。
確認方法は初めて知りました。もう少し調べてみたいと思います。

ところで戻値をlongにしていたのですが、これだと正確な値が帰ってこなく、intにした結果うまく動作しました。

stringの場合は手順を踏む必要があると記憶しているのですが、int以外のlong,doubleなども何か手続きが必要なのでしょうか?
(それとも、単にプログラムミスだったのかも。。)

私の愚問に答えていただき、ありがとうございました。

投稿日時 - 2003-06-17 16:15:54

あわせてチェックしたい
  • DllImportが正しく動作しない ...
  • C# DLL エントリ ポイントが見つかりません。 ...
  • C#のDllImportでuint型をどう指定すればいいのでしょうか? ...
PR

OKWaveのオススメ

教えて弁護士さん!

お金の悩みQ&A特集はこちら