
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が使いたいため、詳しい方ご教授願います。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.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 と書いた方がいいと思います。
No.2
- 回答日時:
C#のlongは64ビットで、VC++のlongは32ビットなので、C#からはintと扱って問題ないでしょう。
stringはデフォルトでマルチバイトで渡されるので、それで問題なければそのまま渡せます。
C#のlong,float,doubleは渡した事がなかったりもしますが、C#のlongをVC++の__int64と受け取る以外はそのままいけそうな気がします(役にたたずすいません)。
この回答への補足
その後色々と試した結果、過去に作った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を作っています。
しかし、これだと前述のようにエントリポイントが見つかりませんとなってしまいます。
他に手続きは必要なのでしょうか?
初心者の質問で本当にすみません。
色々と勉強になりました。
変数のビット数を考慮する必要があるのですね。
これから、色々と試してみたいと思います。
どうもありがとうございました!
No.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 と確認しています。
ありがとうございます。
試行錯誤した結果、動作するようになりました。
確認方法は初めて知りました。もう少し調べてみたいと思います。
ところで戻値をlongにしていたのですが、これだと正確な値が帰ってこなく、intにした結果うまく動作しました。
stringの場合は手順を踏む必要があると記憶しているのですが、int以外のlong,doubleなども何か手続きが必要なのでしょうか?
(それとも、単にプログラムミスだったのかも。。)
私の愚問に答えていただき、ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
acceptをalarmでタイムアウトさ...
-
C言語での引数の省略方法
-
構造体の勉強中です 合計点の高...
-
C言語の関数で戻り値を返す必要...
-
C言語 エラーの原因がわからな...
-
return 1L
-
プログラムがうまく動作しない
-
C#のコンパイルエラーCS0120に...
-
【C++】関数ポインタの使い方
-
インライン展開されているか確...
-
ColorをRGBで指定する方法
-
「指定されたキャストは有効で...
-
C言語 プログラミング
-
Windowsでインターバル・タイマ...
-
DirectX ~テクスチャに値を書...
-
式は定数値が必要です」という...
-
read関数をノンブロッキングで...
-
以下のプログラムをnumber.txt...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数桁10進数の*桁目だけを抽出...
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 エラーの原因がわからな...
-
ラップ関数とはどんなものですか?
-
【C++】関数ポインタの使い方
-
if と配列の組み合わせ
-
(int *)の意味
-
ColorをRGBで指定する方法
-
未解決の外部シンボル _printf...
-
構造体の勉強中です 合計点の高...
-
商と剰余を同時に求める(C言語)
-
C言語で分からないところがあり...
-
式は定数値が必要です」という...
-
C言語での奇数の和
-
std::set<int> で、ある値が何...
-
課題でつまってます・・・
-
int16_t の _t は何?
-
比較回数と交換回数表示について
おすすめ情報