VC++アプリケーションフォームにDLLをリンクする方法

このQ&Aのポイント
  • VC++2010ExpressEditionのアプリケーションフォームでDLLの関数を利用する方法について
  • DLLを呼び出すようにプログラムを書いた際に発生するエラーの解決方法
  • DLLの構成と関数の仕様について
回答を見る
  • ベストアンサー

VC++アプリケーションフォームにDLLをリンク

単純なC++などは適当に使えるのですが、マルチスレッドのプログラムについては初心者です。 VC++2010ExpressEditionのアプリケーションフォームを用いて ボタンを押すと、テキストに入力した数値をDLLの関数に送り、その計算結果を、ラベルに表示する、という単純なプログラムを作成しています。 DLLを利用しないで、Form1内に計算式を作った場合には、正常に動かすことができます。 しかし、DLLの関数を利用する方法がわかりません。 DLLを呼び出すようにプログラムを書いても、ビルドするとエラーが出ます。 インターネット上を30時間位いろいろ調べて試したのですが、分かりませんでした。 もう限界になりましたので、ここに投稿しました。 解決方法を教えて頂けますよう、お願い致します。 DLLは下記のような単純なもので、Sample.cppとSample.defで構成されています。 //+--- Sample.cpp ---+ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include <windows.h> #include <stdlib.h> #include <stdio.h> //---- #define ABC_EXPFUNC __declspec(dllexport) //+------------------------------------------------------------------+ BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { //---- switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } //---- return(TRUE); } //+------------------------------------------------------------------+ ABC_EXPFUNC double __stdcall SecretFunc(double a, double b) { double c = a + b; return(c); } //+--- Sample.def ---+ LIBRARY Sample EXPORTS SecretFunc

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

> では、このDLLを、ボタンを押した時に利用するには、Form1.hなどにどのようにコードを書けばよいのでしょうか。 ...コード読んだ? ちゃんと動作することを確認済みのものを提供しました。

Challenge_2012
質問者

お礼

いや、恐れ入りました。 あれほど短時間に回答頂いたので、てっきり、DLL_sampleだけを作って頂いたと思ってしまいました。 全部のソースが入っていました。そして、きちんと動作しました。 本当に、本当にありがとうございました。 あなた様に、なだれのごとく、よきことがおこりますように!

その他の回答 (3)

回答No.3

> ただ、このDLLは他のソフトも使っており、これを変更することは出来ません。 そのDLLが .h と .lib もいっしょに提供されているなら問題なし。ふつーにリンクすればいい。 そうでなければ、LoadLibrary/GetProcAddress/FreeLibrary することに。

Challenge_2012
質問者

お礼

ご回答ありがとうございました。 作成して頂いたDLLが他のソフトでもそのまま利用できるとのこと助かります。 では、このDLLを、ボタンを押した時に利用するには、Form1.hなどにどのようにコードを書けばよいのでしょうか。 LoadLibrary/GetProcAddress/FreeLibrary などの関数を試したのですが、ビルドするとエラーが出て、 「CLRとMTを同時に利用できない」などと表示されます。 また、これを解決しようと色々いじくっている間に、いっぱいエラーがでて収集がつかなくなりました。 要は、マルチスレッドの使い方が全く分からないので、どこに何を書けばよいのかわかりません。 何か、お手本になるコードやサイトがあれば教えて頂きたいと思います。 よろしくお願いします。

回答No.2

DLLよりも呼び出す側の問題だと思います。 ・呼び出す側のプロジェクトの種類 ・呼び出す側で行っていること (.libのリンク? LoadLibrary? etc.) ・エラーの内容 (基本はエラーメッセージをコピペする。パスなどは基本不要ですが) を書いてもらえれば,なんらかの解やヒントが出せるかもしれません。

Challenge_2012
質問者

お礼

早速のご回答、まことにありがとうございました。 情報不足で申し訳ありません。 プロジェクトの種類は、Visual C++ CLR Windowsフォームアプリケーションです。 ご指摘のように、DLLは問題なく、他のソフトで動いています。 そしてそれゆえに、DLLは変更することは出来ません。 フォームアプリケーションの中にどのようにプログラムすればよいかを教えてください。よろしくお願いします。

回答No.1

なんの問題もなくできちゃいました。 ※ 参考URLの DLL_sample.zip

参考URL:
https://skydrive.live.com/?cid=07c558f8e11e708f#cid=07C558F8E11E708F&id=7C558F8E11E708F%21216
Challenge_2012
質問者

お礼

DLL_sampleを作って頂き、まことにありがとうございました。 ただ、このDLLは他のソフトも使っており、これを変更することは出来ません。 これを利用する、ボタンなどを含むプロジェクトは、Visual C++ CLR Windowsフォームアプリケーションで作りました。 これにどのようなコードを追加すれば、DLLが利用できるか、教えていただければ幸いです。 よろしくお願いします。

関連するQ&A

  • VisualStudio2005でのDLL作成

    開発環境 OS:WindowsXP SP2 SDK:VisualStudio2005 StandardEdition 言語:VC++ Win32コンソールアプリケーションのDLLを選択 空のプロジェクトを使用 作成したいのはVBなどから呼び出せるWin32DLLです。 他のホームページを参考にして以下のようなファイルを作成し ビルド->コンパイルしたところdllファイルはできましたが AccessVBAから参照設定ができませんでした。 どこを修正すればよいか教えてください。 <dlltest.cpp> #define EX __declspec (dllexport) #include <iostream> #include <windows.h> EX int fnWindowHook(void); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call){ case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } EX int hundred(){ return 100; } <dlltest.def> LIBRARY "dlltest1" EXPORTS disp @1

  • EXE1→DLL→EXE2数値を受け渡す方法

    C++プログラムの初級者です。 EXE1の数値をDLLの関数Func1に渡し、そこで計算した結果を関数Func2でEXE2に送るプログラムを作成しています。 下記のようなDLLのコードを作成したのですが、うまく数値を受け渡すことが出来ません。 調べてみると、EXE1⇔DLLとEXE2⇔DLLとは、アドレス空間が別なので、DLLのStatic変数を共有できないようです。 EXE1⇔DLL と EXE2⇔DLL の1対1では数値受け渡しは、正常に動作しています。 具体的に、DLLにどのようなコードを書けば、数値を受け渡すことができるのでしょうか? ご指導よろしくお願いします。 VC++2010ExpressEdition で作成しています。 <DLLのソースコード> ---------------------- #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <iostream> static double aa, bb; __declspec(dllexport) double __stdcall Func1(double a1, double b1) { aa = a1*2; return (double)(aa); } __declspec(dllexport) double __stdcall Func2(double a2, double b2) { return (double)(aa); } BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { //---- switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } //---- return(TRUE); }

  • シンボルをエクスポートするDLLの初歩的トラブル

    VC++6.0で簡単なDLL作成にチャレンジしたところ、ソースファイルの最後のところで、エンドオブファイルのエラーが出ます。教本と同じように書いたつもりですが、何処が異なっているのか分かりません。エラーを出す原因となっている箇所を御指摘下さい。 ↓ソースファイル #include "stdafx.h" #include "SUB.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } SUB_API LONG _stdcall subtract( LONG sub1 , LONG sub2 ) { return( sub1 - sub2 ); } ↓ここからはヘッダーファイル #ifdef SUB_EXPORTS #define SUB_API __declspec(dllexport) #else #define SUB_API __declspec(dllimport) #endif #ifdef __cplusplus extern "C" { #endif SUB_API LONG __stdcall subtract( LONG sub1, LONG sub2 ); #ifdef _cplusplus } #endif --------------------構成: SUB - Win32 Debug-------------------- コンパイル中... StdAfx.cpp コンパイル中... SUB.cpp C:\Program Files\Microsoft Visual Studio\MyProjects\SUB\SUB.cpp(38) : error C2059: 構文エラー : 'end of file' cl.exe の実行エラー SUB.dll - エラー 1、警告 0

  • VC++フォームアプリケーションにDLLをリンク2

    2日前に、同じタイトルで投稿した者です。 http://okwave.jp/qa/q7326569.html その節は素晴らしい回答を頂きありがとうございました。 それを実現するように、作成して頂いたプログラムの修正に取り組んでいるのですが、うまく行きません。 どなたかお力をお貸し下さいm(>o<)m 前回の回答で、指摘されたように、LoadLibrary/GetProcAddress/FreeLibrary を用いて 作成して頂いたプログラムを修正しました。 具体的には、ボタンを押すとSecretFunc関数を呼び出すコードForm1.cppを以下のように修正しました。ビルドしても、エラーは出ません。 次に、このプログラムのReleaseフォルダー内のDLL_sample.dllを 前回、私が投稿したソースコード(http://okwave.jp/qa/q7326569.html)で作成したDLL_sample.dllと置き換えました。 そして、プログラムを起動(WinForm_sample.exe)すると、エラーは発生しないのですが、SecretFunc関数が見つけられず、プログラムの"No DLL"表示の方を通ります。 その原因が分かりません。 プログラムは全て、VC++2010ExpressEditionで作成しています。 もし、お分かりの方がいらっしゃいましたら、ご教授のほどよろしくお願いします。 //修正したForm1.cppのコード #include "stdafx.h" #include "Form1.h" #include "DLL_sample.h" #include <Windows.h> typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT); namespace WinForm_sample { System::Void Form1::btnCalc_Click(System::Object^ sender, System::EventArgs^ e) { System::Double a, b; if ( System::Double::TryParse(txtA->Text, a) && System::Double::TryParse(txtB->Text, b) ) { HINSTANCE hDLL; // Handle to DLL LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer //DWORD dwParam1; //UINT uParam2, uReturnVal; hDLL = LoadLibrary(TEXT("DLL_sample.dll")); if (hDLL != NULL) { lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,"SecretFunc"); if (!lpfnDllFunc1) { // call the function double c = SecretFunc(a,b); txtResult->Text = c.ToString(); // handle the error FreeLibrary(hDLL); //return SOME_ERROR_CODE; } else { // Initializes the variables to pass to the MessageBox.Show method. txtResult->Text = L"No DLL"; } } else { txtResult->Text = L"不正な入力"; } } } }

  • VC++6.0 DLLの作り方

    VC++6.0でWin32 Dynamic-Link Libraryプロジェクトを作成しようとしました。 練習用に足し算と引き算です。 StdAfx.cpp test99.cpp StdAfx.h ReadMe.txt Basetsd.hなど、いろいろなファイルが出来ています。 これを親プログラムから、#include "StdAfx.h"としてリンクさせたいのですが、 StdAfx.hに、関数を公開しなければならないと思います。 StdAfx.hは、何を行うヘッダーファイルなのか? 何処に何を記述するのがベストでしょうか? VC++の生成した日本語のコメントの意味が今ひとつ理解できません。 以下はtest99.cpp #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } __declspec(dllexport) int WINAPI tasizan(int a,int b) {return (a+b);} __declspec(dllexport) int WINAPI hikizan(int a,int b) {return (a-b);} 以下はStdAfx.cpp #include "stdafx.h" 以下はStdAfx.h #if !defined(AFX_STDAFX_H__D849B748_701B_483D_9457_AA6096D78FB0__INCLUDED_) #define AFX_STDAFX_H__D849B748_701B_483D_9457_AA6096D78FB0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN #include <windows.h> //????????__declspec(dllexport) int WINAPI tasizan(int,int); //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。 #endif // !defined(AFX_STDAFX_H__D849B748_701B_483D_9457_AA6096D78FB0__INCLUDED_)

  • [VC++2008].dllが見つからない

    Visual Studio C++ 2008で自作DLLを使用したプログラムを作成しています。 ソースツリーが以下のようにあります。 main.cpp で #pragma comment(lib,"myutil_d.lib") #include "myutil.h" とすると、コンパイルは成功するのですが、prog1.exeを実行すると: 「myutil_d.dllが見つからなかったため、このアプリケーションを開始できませんでした。」 と出てきてプログラムが始まりません。 これを解決する方法をご教授いただけるでしょうか? (MYPROGROOT) |-include | |-myutil.h | |-lib | |-myutil_d.dll | |-myutil_d.exp | |-myutil_d.lib | |-prog1 | |-Debug | | |-prog1.exe | | |-prog1.ilk | | |-prog1.pdb | |-prog1 | | |-Debug | | | |-BuildLog.htm | | | | ... | | | | | | |-main.cpp | | |-prog1.vcproj | | | |-prog1.ncb | |-prog1.sln | |-prog1.suo | |-prog2 |-Debug | |-prog2.exe | |-prog2.ilk | |-prog2.pdb |-prog2 | |-Debug | | |-BuildLog.htm | | | ... | | | | |-main.cpp | |-prog2.vcproj | |-prog2.ncb |-prog2.sln |-prog2.suo 「>ツール>オプション>プロジェクトおよびソリューション」下 インクルード ファイル :$(MYPROGROOT)\bin ライブラリ ファイル :$(MYPROGROOT)\include もちろんmyutil_d.dllを(MYPROGROOT)\prog\Debug\ に配置するとプログラムは動くのですが、prog1, prog2, と多数のプログラムで myutil_d.dllを使用するため、バージョン管理のために統一のディレクトリで .dllファイルを管理したいと考えています。

  • DLLファイルを分けたい

    Win2K VC++ 6.0 でDLLを作成しています。 現在DLLの関数が多すぎて作業しにくいですが、 3つに分けたいですが可能でしょうか。 Test.def Test.h Test.cpp Test.defの中身  FunA FunB FunC FunD FunE FunF FunA,FunB ==> A.CPP FunC,FunD ==> B.CPP FunE,FunF ==> C.CPP にしたいですが、方法がわかりません。

  • VC2005のDLLを6.0で呼び出すには

    VC 2005 Pro Editionで作ったライブラリ(ヘッダ、lib、dll)を頂きました。    頂いたDLLの形式は定義ファイル.defを使わない形式、declspec(dllexport)を使う形式の方です。  呼び出し側はVC6.0EnterPrize(SDK)を使います。 (諸事情により6.0以上にUPすることは不可能)     まず、静的リンクをし、関数を呼び出してみました。  (設定のリンクよりlibをリンクさせ、ヘッダをインクルードして)  すると以下のメッセージが出てしまいます。 リンク中... Dialog1.obj : error LNK2001: 外部シンボル ""__declspec(dllimport) void __cdecl Init(unsigned char *,unsigned char *,unsigned char *,unsigned char *)" (__imp_?Init_Card@@YAXPAE000@Z)" は未解決です Debug/CardMake.exe : fatal error LNK1120: 外部参照 1 が未解決です 。 link.exe の実行エラー    色々やってみましたが、このエラーから回避できませんでした。  ヘッダ自体に #ifdef _USRDLL #define DLL_PORT __declspec(dllexport) #else #define DLL_PORT __declspec(dllimport) #endif    の宣言があるので、別に特別なことをしなくても、大丈夫そうなのですが、何故か出来ません。  次に動的リンクを行っていました。  するとLoadLibraryでエラーになり、GetLastErrrorで14001(エラーメッセージはつかめず)が返ってきました。 (色々調べたところ定義ファイルがないと動的リンクはできないようですね)    というわけでにっちもさっちも行かなくなった状況です。  そこでご質問です。 (1)定義ファイルを使わない形式のライブラリ(暗示的に定義されているもの)はどのように呼び出させばよいでしょうか? (2)2005のライブラリを6.0から呼び出すことは可能ですか?  また呼び出す方法は?  すいませんがご回答をお願いします。

  • VC++でコンパイルできてg++でコンパイルできない

    VC++6.0でコーディングしてコンパイル→実行できたのでLinuxにソースを移してg++でコンパイルしてみました。ところがコンパイルで (中略) InFunction 'App::App[not-in-charge]()' undefined reference to 'MyClass::MyClass[in-charge]()' と言うメッセージが表示されコンパイルできません。 ソースを簡単に書くと、 /***** main.cpp *****/ #include "App.h" App app; int main() { } /***** App.h *****/ #inndef __APP_H_ #define __APP_H_ #include "MyClass.h" class App { MyClass *obj; public: App(); }; #endif /***** App.cpp *****/ #include "App.h" App::App() { obj = new MyClass(); } /***** MyClass.h *****/ #ifndef __MYCLASS_H_ #define __MYCLASS_H_ class MyClass { public: MyClass(); } #endif /***** MyClass.cpp *****/ #include "MyClass.h" MyClass:MyClass(){} と言った具合です。エラーメッセージはAppがMyClassのコンストラクタがどういったものか判らない旨を通知しているのだと思うのですが#includeはきちんと行われているように見られます。 コンパイル順かとも考え g++ main.cpp App.cpp MyClass.cpp g++ main.cpp MyClass.cpp App.cpp と試してみましたが同様の現象です。凡ミスかとは思うのですがなかなか客観的に見られず困っています。

  • DLL作成時、defファイルを使いたくない

    また質問させて下さい。 Visual Studio2005でDLLを使ったプログラムを作ろうとしています。 defファイルを利用すると、そのDLLファイルを作成できるのですが、 __declspec(dllexport)を利用すると、DLLファイルのその関数を読めなくなってしまいます。 なぜでしょうか? 下記は、MFCで、dll_test7というプロジェクトを作り、そのdll_test7.hのコードのすぐ下に その関数を書きました。(これがダメだと思うのですが…) //●Visual Studioのプロジェクト作成で、生成される部分 // dll_test7.h : dll_test7.DLL のメイン ヘッダー ファイル // #pragma once __declspec(dllexport) void __cdecl test0(void); #ifndef __AFXWIN_H__ #error "PCH に対してこのファイルをインクルードする前に 'stdafx.h' をインクルードしてください" #endif #include "resource.h" // メイン シンボル // Cdll_test7App // このクラスの実装に関しては dll_test7.cpp を参照してください。 // class Cdll_test7App : public CWinApp { public: Cdll_test7App(); // オーバーライド public: virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP() }; //■作成した関数 __declspec(dllexport) void __cdecl test0(void) { CString cs; cs="aa"; ::AfxMessageBox(cs); } 上記は、defファイルを利用するとこの関数を呼び出せます。 以上、どうぞよろしくお願い致します。