DLLをソフトでコンパイルして作成

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
めにゅーづくり

DLLをソフトでコンパイルして作成

#1

投稿記事 by めにゅーづくり » 7年前

Microsoft visual studio 2010 c++ expressのWindowsフォームアプリケーションで作業してます。
時間の都合上C++/Cliは必ず使わなければならない状況です。
今回ソフト上でcppファイルをつくりバッチファイルを用いてコマンドプロンプトからコンパイルしてDLLを作成して
それを動的にロードして使うソフトウェアを作成しているのですが、
つくったDLLをLoadLibraryで読み込むとAccessViolationExceptionエラーが生じてしまいます。

DLLは作成されているのですが、なぜ使えないのでしょうか?
コードの間違いのご指摘をお願いします。

コード:

	// Form1.h
          private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {		
            String^toolname;
			 toolname=textBox1->Text;

			 String^savecpppath="ファイルへのパスがかいてあります";
           //richTextBox1にコードを書きます。
			 richTextBox1->SaveFile(savecpppath+toolname+".cpp", RichTextBoxStreamType::PlainText );

			 //batファイルを作る もともと用意されたバッチファイルから読み込み書きます。
			   String^ fileName = "batfile.txt";
	  StreamReader^din=gcnew StreamReader(fileName,System::Text::Encoding::GetEncoding("shift-jis"));
	  int a=0;
	  int i=0;
      String^ str;
      int count = 0;
	  String^w;
      while ((str = din->ReadLine()) != nullptr) 
      {
		  a=count;
         count++;
        marshal_context^c=gcnew marshal_context();
			 string s=c->marshal_as<string>(str);
			 battext[a]=s;
	  }
	  String^ outputName = "vccmd.bat";
      StreamWriter^ sw = gcnew StreamWriter(outputName,false,System::Text::Encoding::GetEncoding("shift-jis"));
	  for (i=0;i<=2;i++){
	  w=marshal_as<String^>(battext[i]);
	  sw->WriteLine(w);
	  }
	  sw->WriteLine("cl /LD "+toolname+".cpp");
	  w=marshal_as<String^>(battext[3]);
	  sw->WriteLine(w);
	  sw->Close();
			 //batファイルを起動する。
			 Process^ batrun = gcnew Process;

			 batrun->Start("vccmd.bat");

コード:

//vccmd.batの内容
cd C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin
call vcvars32.bat
cd (DLLのあるパスが書かれている)
exit

コード:

//試験用のDLLプログラム これをrichtextBoxに入力します。
#define     _One_MAKE_DLL_
#include    "c11dll.h"

/*  
    外部に公開され共有される関数MyFunction
    その機能は、与えられた整数を100で割った余りを返す。
*/
__PORT int  MyFunction(int x)
{
    return  x%100;
}

コード:

//.dllと同じ場所に置いてあるヘッダファイル "c11dll.h"
#ifdef  _One_MAKE_DLL_
#   define  __PORT  __declspec(dllexport)   /*  DLLを作る場合   */
#else
#   define  __PORT  __declspec(dllimport)   /*  DLLを使う場合   */
#endif

__PORT  int MyFunction(int);

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: DLLをソフトでコンパイルして作成

#2

投稿記事 by h2so5 » 7年前

C++/CLIで書かれているコードはバッチファイルを操作しているようですが、何のためのプログラムなんでしょうか?
あと、DLLを呼び出しているプログラムはどれなんでしょう?

めにゅーづくり

Re: DLLをソフトでコンパイルして作成

#3

投稿記事 by めにゅーづくり » 7年前

h2so5 さんが書きました:C++/CLIで書かれているコードはバッチファイルを操作しているようですが、何のためのプログラムなんでしょうか?
あと、DLLを呼び出しているプログラムはどれなんでしょう?
ソフト自体にC言語を入力してDLLを作りソフトに関数を自主的に追加できるプログラムを作ろうとしています。
申し訳ありません。DLLを呼び出すプログラムを書いていませんでした。

コード:

//dllload.cpp dllをロードする部分は関数でForm1とは別の場所にかいてあります。
#include "stdafx.h"
#pragma hdrstop
#define     STRICT
#include    <windows.h>
#include    <stdio.h>
#include    <stdlib.h>

/*  C11Dll.DLLにあるMyFunctionの型を定義する    */
typedef int (*TFUNC)(int);

int dllload(int*number)
{
	int x;
    HINSTANCE   hInstDLL;       /*  DLLのインスタンスハンドル                */
    TFUNC       DllFunction;    /*  DLLのMyFunctionへのポインタ    */
     /*  ここでDLLをロードする    */
    if((hInstDLL=LoadLibrary("追加されたDLLのパス"))==NULL)
        abort();
	 
    /*  ここでMyFunction()のポインタ値を取得する    */
    DllFunction=(TFUNC)GetProcAddress(hInstDLL,"MyFunction");

    /*  実際に使ってみる    */
    x=DllFunction(123456);
	*number=x;
    /*  ここでDLLを開放する  */
    if(!FreeLibrary(hInstDLL))
        abort();

    return 1;
}

コード:

//dllload.h
#ifndef _INC_DLLOAD   //まだ読み込まれていなければ以下の処理をする
#define _INC_DLLOAD    //すでに読み込まれているという目印をつける

int dllload(int*number);

#endif 
これをForm1のほうで呼び出して使っていますが、この関数が動いた時にエラーが生じます。

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: DLLをソフトでコンパイルして作成

#4

投稿記事 by h2so5 » 7年前

めにゅーづくり さんが書きました: ソフト自体にC言語を入力してDLLを作りソフトに関数を自主的に追加できるプログラムを作ろうとしています。
どう考えてもVisualStudioを使ってDLLを作ったほうが早いでしょう。
誰がシンタックスハイライトもデバッガも使えないRichTextBoxでコードを書きたがるのでしょうか。

めにゅーづくり

Re: DLLをソフトでコンパイルして作成

#5

投稿記事 by めにゅーづくり » 7年前

h2so5 さんが書きました:
めにゅーづくり さんが書きました: ソフト自体にC言語を入力してDLLを作りソフトに関数を自主的に追加できるプログラムを作ろうとしています。
どう考えてもVisualStudioを使ってDLLを作ったほうが早いでしょう。
誰がシンタックスハイライトもデバッガも使えないRichTextBoxでコードを書きたがるのでしょうか。
確かにその通りなのですが、この方法で作ることはできないのでしょうか?

YuO
記事: 941
登録日時: 9年前
住所: 東京都世田谷区

Re: DLLをソフトでコンパイルして作成

#6

投稿記事 by YuO » 7年前

作ったDLLをDependencyWalkerなりDumpBinなりでエクスポートリストを確認してみてください。
"MyFunction"ではなく"?MyFunction@@YAHH@Z"という関数名でエクスポートされているはずです。
"MyFunction"という名前でエクスポートしたいのであれば,.DEFファイルを書いてください。

というか……デバッグしましょう。
IDEでデバッグ実行すれば,Access Violationのタイミングでブレイクします。
呼び出し履歴を遡って,自コードまで戻って,関係しそうな変数値を調べれば,DllFunctionの値がnullptrであることがわかったはずです。
さらに,GetProcAddress関数がnullptrを返したのだから,その場合にはGetLastError関数で原因を調べる様にしていれば,エラー値が127であることもわかったはずです。
この値は,net helpmsg 127とコマンドラインから打つと「指定されたプロシージャが見つかりません。」となります。
以上から,ちゃんと調べれば,エクスポートされた関数が無いことがわかったはずです。

まずはデバッグやエラー対策といった,基本的なところを押さえた方がよいと思いますよ。

閉鎖

“C言語何でも質問掲示板” へ戻る