DLLの(正しい?)作成方法 – 固定ページ 2 – プログラミング – Home

DLLの(正しい?)作成方法
 
通知
すべてクリア

[解決済] DLLの(正しい?)作成方法

固定ページ 2 / 3

なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>tetrapod様

説明ありがとうございます。
簡単で、使いやすくするためには h,lib.dllを提供してもらうのが一番良いという事で
すね。
h.lib.dllの3点セットでもらえるかどうかはっきりしていないのでそこをまずははっきり
させたいと思います。どうしてもdllのみという場合は、利用側で適切な typedef とキャ
ストをする必要があるってことを理解の上ってことですね。
今回の質問でみなさんから教えて戴くまで、dllのみで使えるものだとばかり思っていま
した。勉強になりました。ありがとうございます。

私の周りはC#の開発ばかりでして、VC++で作成したDLLをC#で使う場合、必要なのはdllだ
けで良くて、なんだかすごく簡単にimportできるみたいなのです。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>みい様

FreeLibraryですか。
調べてみます。ありがとうございます。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>みい様

GetProcAddressに失敗した場合は、必ずFreeLibraryを呼び出し、DLLを解放します。
ですね。

利用側で typedef とキャストをしてdll内の関数を使うケースの場合に、GetProcAddres
で失敗したら、FreeLibraryを忘れずに。ってことで良いでしょうか。


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

FreeLibraryはLoadLibraryと対になります。
LoadLibraryで確保したdllを、最後にFreeLibraryで解放します。


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

GetProcAddresの成否ではなく、
LoadLibraryに成功した場合DLLを使い終わったら
必ずFreeLibraryを呼び出し解放します。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>みい様

正確な情報を教えていただきありがとうございます。
GetProcAddressを使ったら忘れずにLoadLibraryを呼び出します。


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

念のため…

GetProcAddressで取得した関数アドレスを使用する間は
FreeLibraryしてはいけません。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>みい様
わざわざ、ありがとうございます。
まだまだ初心者ですが、さすがに書き間違いしない限り大丈夫です。

スレッドの時は終わりを確認しないでクローズしてますが、スレッド走らせてすぐに制御
を返したいからスレッド終わるの待っていられないし、良いのだと思っています…。
HANDLE hThread = (HANDLE)_beginthreadex(0, 0U, TEST,0 0, &threadID);
CloseHandle(hThread);


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> 私の周りはC#の開発ばかりでして、VC++で作成したDLLをC#で使う場合、必要なのはdllだ
> けで良くて、なんだかすごく簡単にimportできるみたいなのです。

C#からネイティブDLL関数呼び出すの,そんなに簡単ではないですよ。
https://msdn.microsoft.com/ja-jp/library/26thfadc.aspx
とか
https://msdn.microsoft.com/ja-jp/library/eaw10et3.aspx
とかをある程度理解しておかないと,痛い目に遭いますから。
# もちろん,C++/CLIのマネージクラスはCLIのメタデータがあるため,簡単に使えますが。

基本的に,C#からネイティブDLL関数を呼び出すにも,ヘッダファイルはないと困ります。
というよりも,ヘッダファイルの情報がないとメソッドを書けません。
DLLからわかるのは基本的に関数名だけなので,引数の数や型,戻り値の型がわからないためで
す。

これは,
> どうしてもdllのみという場合は、利用側で適切な typedef とキャ
> ストをする必要があるってことを理解の上ってことですね。
に書かれている,「適切な typedef」ってどうやって知りますか,ということでもあります。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>YuO様

URLの紹介ありがとうございます。
一読しましたが、初見の単語がありすぎて理解が追い付きません。

C#の方だと、VCで作ったdllだけをコピーして、クラス内で

[DllImport(EXPORTTEST2.dll, CallingConvention = CallingConvention.Cdecl)]
static extern int warizan(int i);

って書いておけば使えると思っていたのですが、違うのでしょうか。C#の方も勉強しない
といけませんね…。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

そういう単純型を取り扱うだけなら提示の方法でできるっす。
marshal が必要な型になると C# のほうも知っておかないと無理っす。

... って今まで dll 公開関数を __stdcall にしてなかったのはわざと?
内部で使っている作業用関数は __stdcall だろうが __cdecl だろうがどうでもいいけど
公開している入口関数は __stdcall のほうが一般的だよ。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>tetrapod 様

私がど素人だというのは、怒涛の質問投稿でご存知だとは思いますが、「DLLを作る・そ
れを使う」という作業が来て、方法をネットで調べて見つかったのを使っているので、ど
れが良いとかどれが一般的とか知らず、コーディングしている状態なのです。

__stdcallの方が一般的という情報ありがとうございます。

最近は初めての作業内容ばかりで迷走してます。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> [DllImport(EXPORTTEST2.dll, CallingConvention = CallingConvention.Cdecl)]
> static extern int warizan(int i);
> って書いておけば使えると思っていたのですが、違うのでしょうか。C#の方も勉強しない
> といけませんね…。

warizan関数の引数がint型1つで,戻り値の型がint型,呼び出し規約がcdeclという情報はどう
やって知ったのでしょうか。
# 通常はそれを知るための方法はヘッダファイルを調査する,であるわけですが。
これは,
> 「適切な typedef」ってどうやって知りますか,ということでもあります。
と同じ質問でもあります。


返信引用
なおぞう
 なおぞう
(@なおぞう)
ゲスト
結合: 9年前
投稿: 143
Topic starter  

>YuO様

説明ありがとうございます。

今回のテストでは、自分でDLLを作って自分で使うから、dllの持つ関数の引数も戻り値も
分かっており、使う側のコードを書けているってことですね。

dllだけを提供する(してもらう)場合はdllが持つ関数情報を知るためにヘッダか関数仕
様書が無いと駄目なのですね。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

https://msdn.microsoft.com/ja-jp/library/784bt7z7.aspx
これは、見てますか?
>typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
 これを必要な関数分作らないといけないですね。
実際にこれを作るとなると、結果的に自分でヘッダーファイルを作ることになりますね。

DLLの開発者から、extern C 又は extern C++の宣言部分だけテキストデータで
もらえると楽ですよね。

>typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
この宣言部分は開発者に掲示をお願いしてもいいと思いますね。
 
 


返信引用
固定ページ 2 / 3

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました