ここから質問投稿すると、最大4000ポイント当たる!!!! >>

C++プロジェクト(Windowsフォームアプリ)を作成し、あるサイトで公開されているDLLを実装し→コンパイル→デバッグ実行させた所、問題なく動作が確認できたのですが、
クラスライブラリで作成したC++新規プロジェクトに同じくDLLを実装し、同一ソリューション内にC#又はC++でWindowsフォームアプリを作成し、先に作成したクラスライブラリプロジェクトを参照させる形態で作成した際に、コンパイル→デバッグ実行させた所、コンパイルは通ったのですがデバッグ実行時に、DLLを参照しようとしたタイミングで
「DLL参照時に指定されたモジュールが見つかりません。(HRESULT からの例外 0x8007007E) が発生してしまう。」
というエラーが発生してしまいました。

何故Windowsフォームアプリ単体時にはDLLが参照できたのに、クラスライブラリにし複数プロジェクトにして実行するとエラーが発生してしまうのか、どなたか原因、解法等 心得ておられましたら御指南のほど宜しくお願いします。

以下 事象詳細です。
開発環境:Microsoft Visual Studio 2008
公開DLL:USB-IOを制御する目的のUSBIODLLDemo.dllというDLLです。

<成功時>
1.C++プロジェクト(Windowsフォームアプリ)新規作成
2.DLLがインストールされているフォルダから.dllファイル, .hファイル、.libファイルをコピーしプロジェクト新規作成したフォルダにコピーする
3.プロジェクトのプロパティ→構成プロパティ→リンカ→入力→追加の依存ファイル に.libファイル名を記入
4.ダウンロードの.hファイルから
__declspec(dllimport) BYTE __stdcall GetNo(void);
__declspec(dllimport) void __stdcall P1Write(BYTE newVal);
__declspec(dllimport) BYTE __stdcall P1WriteBit(BYTE Bit, BOOL Tf01);
__declspec(dllimport) BYTE __stdcall P1Read(void);
 をコピーしstdafx.h へ貼付け。
5.stdafx.hへ貼り付けた宣言がこのままではコンパイルが通らなかったため
#define BYTE unsigned char
#define BOOL bool
 を追記。
6.ダウンロードしたDLLの関数を使用した一文を実装
7.コンパイル→デバッグ実行→ 無事実行完了!

<エラー発生時> *下記事象ではC#Winフォームアプリを挙げていますがC++Winフォームアプリで試しても同じ結果になりました。
1.C++プロジェクト(クラスライブラリ)新規作成
2.DLLがインストールされているフォルダから.dllファイル, .hファイル、.libファイルをコピーしプロジェクト新規作成したフォルダにコピーする
3.プロジェクトのプロパティ→構成プロパティ→リンカ→入力→追加の依存ファイル に.libファイル名を記入
4.ダウンロードの.hファイルから
__declspec(dllimport) BYTE __stdcall GetNo(void);
__declspec(dllimport) void __stdcall P1Write(BYTE newVal);
__declspec(dllimport) BYTE __stdcall P1WriteBit(BYTE Bit, BOOL Tf01);
__declspec(dllimport) BYTE __stdcall P1Read(void);
 をコピーしStdafx.h へ貼付け。
5.Stdafx.hへ貼り付けた宣言がこのままではコンパイルが通らなかったため
#define BYTE unsigned char
#define BOOL bool
 を追記。
6.ダウンロードしたDLLの関数を使用した一文を実装(公開関数として)

7.C#プロジェクト(Windowsフォームアプリ)新規追加 *C++(Windowsフォームアプリ)でやっても同じ結果になりました。
8.新しい参照の追加で上のクラスライブラリプロジェクトを追加
9.フォームアプリ側でクラスライブラリプロジェクトの関数を実行する処理を実装
clsTest ctst;
ctst.Exec();

10.コンパイル→デバッグ実行→DLLを参照しようとしたタイミングでエラー発生!
「DLL参照時に指定されたモジュールが見つかりません。(HRESULT からの例外 0x8007007E) が発生してしまう。」
*クラスライブラリ側の、DLLの関数を呼んでいる部分をコメントアウトするとエラー無く実行できてしまいます。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

やるならば ソリューション名をつけて複数のプロジェクトをまとめたほうがいいように思います



VC++/C#で新規にプロジェクト(ソリューション)を生成する際のダイアログの『ソリューションのディレクトリを作成』にチェックを入れて
『USBIODEMO』などといった具合にします
その中に.NET用のクラスライブラリのプロジェクトを作成します
こうすると
USBIODEMO\Debug(または Release)に出来上がったDLLが生成されます
同じように テスト用のFormアプリをVCのプロジェクトで作成します
コンパイル/リンクがうまくいけば 上記のフォルダに EXEが生成されます
この状態でFormEXEのデバッグを行ってやれば 質問のようなエラーは回避できると思います

C#の場合は 元の『USBIODLLDemo.dll』をC#のプロジェクトの『bin\debug(またはRelease)』にコピーしないといけないでしょう

つまりは クラスライブラリのDLLは見つかったが 元の『USBIODLLDemo.dll』が見つからなかった
という現象ではないかと思います

アプリの参照はクラスライブラリーまでなのでクラスライブのDLLまではコピーしたりする面倒を見てくれます
クラスライブラリが参照しているDLLまで面倒見てくれないためなのかもしれません

DLLの検索順についてWebなどで検索してみましょう
    • good
    • 0
この回答へのお礼

丁寧な御指南ありがとうございました。
事象を詳細に説明して頂いた事で非常に参考になりました。
お陰様でC++Winフォームのケース、C#Winフォームのケース共に解決致しました。

<↓解決詳細です↓>
・C++winフォームの場合、USBIODLLDemo.dllをソリューションの階層のDebugフォルダに追加する事で解決致しました。
・C#winフォームの場合、御指南頂きました通り USBIODLLDemo.dll をC#プロジェクトのbin\Debugに追加する事で解決致しました。

お礼日時:2009/10/23 10:05

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC# DLL エントリ ポイントが見つかりません。

C#で作成したDLLをC#から呼出したいのですが、うまくいきません。

// トリガ
private void button2_Click(object sender, EventArgs e)
{
string ans = DLL.moji();
MessageBox.Show(ans);
}

// DLL呼出し用クラス
class DLL
{
[DllImport("LibCsharp.dll")]
public static extern string moji();
}

// DLL(LibCsharp.dll内容)
class AddClass
{
public static string moji()
{
return ("テスト");
}
}

上記で実行すると「EntryPointNotFoundException DLL 'LibCsharp.dll' の 'moji' というエントリ ポイントが見つかりません。」となります。

プロジェクトの参照設定にはLibCsharpを追加しています。
Web上で調べたのですが、解決には至っておりません。

申し訳ありませんが、よろしくお願いします。

C#で作成したDLLをC#から呼出したいのですが、うまくいきません。

// トリガ
private void button2_Click(object sender, EventArgs e)
{
string ans = DLL.moji();
MessageBox.Show(ans);
}

// DLL呼出し用クラス
class DLL
{
[DllImport("LibCsharp.dll")]
public static extern string moji();
}

// DLL(LibCsharp.dll内容)
class AddClass
{
public static string moji()
{
...続きを読む

Aベストアンサー

#1です。

私もc#で簡易な独自ライブラリを構築しようとしていたので調べてみました。
結果として参照の追加でdllを直接、指定するだけで使用可能だと分かりました。
(「参照設定」右クリック→「参照の追加」→「参照」タブ選択→DLLを選択)


まず基本的な知識としてdllには3種類あると覚えて下さい。

・レガシー(古い遺産)dll
・active-x dll
・.net dll


私はレガシーdll時代の知識しかありませんでした。
この頃のdllを使用するためには、dll本体以外に以下のファイルが必要でした。

・ヘッダファイル
・ライブラリ(lib)ファイル
・defファイル(場合による)


c#で作られたdllは[.net dll]となり、[.net freamwork]上で動作する各種の言語で使用出来るようにするため、煩わしいlibファイルやヘッダファイル等を削除する方向でdllが進化しているのだと思われます。

ネット検索をしていて見つけたのですが、[.net dll]で作成されたFTPクライアントのライブラリがありました。
(.NET用FTPクラスライブラリ (TKFP.DLL) )

どの言語で作られているのか分かりませんが、[.net dll]で作られているため、c#およびvbで使用可能のようです。
追加したdll内に含まれているクラスや関数に対してオブジェクトブラウザで概要が表示出来るようにXMLファイルで概要を記述出来るようなのですが、詳細まで調べることが出来ませんでした。
(申し訳ありません。)

#1です。

私もc#で簡易な独自ライブラリを構築しようとしていたので調べてみました。
結果として参照の追加でdllを直接、指定するだけで使用可能だと分かりました。
(「参照設定」右クリック→「参照の追加」→「参照」タブ選択→DLLを選択)


まず基本的な知識としてdllには3種類あると覚えて下さい。

・レガシー(古い遺産)dll
・active-x dll
・.net dll


私はレガシーdll時代の知識しかありませんでした。
この頃のdllを使用するためには、dll本体以外に以下のファイルが必要でした。

・...続きを読む

QC# インスタンスの破棄

C#でインスタンスの破棄を明示的に行いたいのですが、
実際の開発現場では、どのように行っているのでしょうか?

自分で調べると「ガベージコレクタ」が暗黙的に行っているようですが明示的には行わないのが普通なのでしょうか?
もしくは、「Dispose」を使用して明示的に行うのが普通なのでしょうか?

実際に開発されている方からすると簡単な事かもしれませんが教えて頂けると助かります。

以上ですが、よろしくお願いいたします。

Aベストアンサー

結論から言うと、どちらでも良いです。
できれば生成から破棄まで考えて開発できると良いですね。

ガベージコレクションが実行されることで自動開放されますから、
一切.close()や.dispose()を使わなかったとしてもプログラムが
不正終了してしまう事はほとんどありません。

実際の開発では使わなくなったものを使わなくなった時点で
明示的に破棄することが多いです。正確には明示的に破棄するもの、
明示的に破棄しないもの、の2種類に分類しています。

例えばファイルを読み書きするストリーム系のオブジェクトや
データベースとのコネクションなどです。これは開発会社や
開発チーム、案件によって若干違っていて、徹底するところや
適当なところもあります。個人的には徹底したい派ですが。。。

ガベージコレクションが発生するとプログラムの実行動作が
遅くなり、また瞬間的に大きな負担がかかることがあります。
そのため全てをガベージコレクタに任せるのではなく、
明示的に開放できるもの、メモリを大量に消費するものは
その都度、適切に開放していくことで処理効率が良くなります。

プログラミング関連の調べ物で、サンプルソース等を見ることが
あるかと思います。この時サンプルで明示的に開放していたら、
それは明示的に開放したほうが良いもの、と思いましょう。
これだけでもステップアップになりますね。

結論から言うと、どちらでも良いです。
できれば生成から破棄まで考えて開発できると良いですね。

ガベージコレクションが実行されることで自動開放されますから、
一切.close()や.dispose()を使わなかったとしてもプログラムが
不正終了してしまう事はほとんどありません。

実際の開発では使わなくなったものを使わなくなった時点で
明示的に破棄することが多いです。正確には明示的に破棄するもの、
明示的に破棄しないもの、の2種類に分類しています。

例えばファイルを読み書きするストリーム...続きを読む

QAPI関数(DLL)の呼び出しにおいて、DLLの格納場所は?

お世話になります。
VB.NETでAPI関数を呼び出す場合にまず、API関数を格納しているDLLを宣言しなけれならないと下記URLにあります。
(http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html)

(a)DllImport属性を利用する方法
<System.Runtime.InteropServices.DllImport("DLL名")> _
Function API関数名(仮引数)
End Function
(b)Declareステートメントを利用する方法
Declare Function API関数名 Lib "DLL名" (仮引数)

そこで、質問なのですが、(a)、(b)どちらの方法で実現する場合においても、DLLの格納場所はC:\Windows\System32でないといけないのでしょうか?(実際にコーディングしてもSystem32フォルダにないとエラーになってしまいます。)
任意のフォルダにDLLを格納し、そこを参照できるようにできるのでしょうか?
また、一般常識としてDLLはSystem32フォルダに格納しておかないといけないものなのでしょうか?

以上、よろしくお願いいたします。

お世話になります。
VB.NETでAPI関数を呼び出す場合にまず、API関数を格納しているDLLを宣言しなけれならないと下記URLにあります。
(http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html)

(a)DllImport属性を利用する方法
<System.Runtime.InteropServices.DllImport("DLL名")> _
Function API関数名(仮引数)
End Function
(b)Declareステートメントを利用する方法
Declare Function API関数名 Lib "DLL名" (仮引数)

そこで、質問なのですが、(a)、(b)どちらの方法で実現する場合...続きを読む

Aベストアンサー

DLL名にパスを含んでいない場合は
1) EXEファイルのカレントフォルダ
2) Windowsのシステムフォルダ(Win9x系ならWindows\Sysytem・WinNT系ならWindows\System32)
3) Winddows\Systemフォルダ
4) Windowsフォルダ
5) 環境変数PATHの設定フォルダ
といった順番でDLLを探すと思います
WinNT系へインストールする際にフォルダの権限などが原因で独自のDLLをWindows\System32へ書き込み出来ないとか
アンインストールなどの機能を提供しない
などの要因によって DLL自体を実行ファイルと同じフォルダに置くこともありますよ

『DLLを必ずWindows\System32に置きなさい』といった規約はありません

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む

QVB.NETで、DLLを頂いたんですが・・

VB.NETでプログラムを作成しているのですが、
DLLを頂きました。
このDLLをプログラムで使いたいのですがよくわかりません。
(1)DLLは実行ファイルにおけばいいんですよね?
(2)DLLを参照しろっていう設定は必要ですか?
(3)DLLには、プロパティ、メソッド、イベントとあるみたいなんですが、これらを宣言しないといけないと思うのですがどうやればいいのでしょうか?
(4)下のような資料もらったのですがVBcnvというのが定義されていないとエラーがでるのですがどうやって宣言するのでしょう?
private <任意名> as VBcnv

(5)libファイルも一緒にあったのですが、どういう風に使えばいいのでしょうか?何につかうのでしょうか?
すいません、どなたかお助けを~

Aベストアンサー

> 参考資料にはVB6.0のdll追加方法が書いてありまして、それには、参照設定という画面が書いてあります。

それならCOMですね。

>(1) 

インストーラが用意されていないのであれば、手動でレジストする必要があります。

>(2) 

VS.NETのプロジェクトがCOMを参照する必要があります。

>(3)
必要ありません。
VS.NETのプロジェクトがCOMを参照すれば自動的にラッパークラスが作成されます。
オブジェクトブラウザでプロパティ、メソッド、イベントを確認できます。

>(4)

private <任意名> as new ラッパークラス名

>(5)

謎。

Qアプリケーション終了時例外エラー(アクセス違反)の調査方法について

大変困っています。

アプリケーションが終了するときに「アクセス違反」がワトソン博士によって取得されています。
当方アプリケーションなどに弱く、解決策の想像が付きません。どなたかご教授お願いいたします。

<解決策例>
・どういったスキルを持った人にどの様な調査を進めさせれば良いのか。。。
・以前同様な事があり原因は○○だった
・恐らく○○だろう
 など、お願いいたします。

<ユーザ報告>
処理終了し、画面が消えたところでワトソン博士のメッセージが表示された

<ログ抜粋>
例外番号c0000005(アクセス違反)

ファンクション:RtlDestroyHeap
~略~
フォールト → 77f6d672 8908 mov [eax],ecx ds:09000001=00000000

<備考>
開発環境:MSVC6.0
動作環境:Windows NT4.0 SP6a
発生頻度:2回/年
使用頻度:2~3回/(平日)

以上、よろしくお願いします。

Aベストアンサー

発生頻度が年2回というのはなかなか厳しい条件ですね。

さて・・・

「私であれば、次の手順で調査を行います。」という書き始めで延々とデバッグ方法を書いていたのですが、書き終わってからちょっとGoogleで検索したら、ひょっとするとちょうど質問者さんのトラブルと同じかもしれない現象がMicrosoftのKBにありました。

場所はここです: http://support.microsoft.com/kb/168006/ja

要点をかいつまんで書くと、MSVCRT/MFCのDLLのバージョン不整合でエラーが発生することがある、という内容です。KB自体は特定のアプリケーションについて書かれていますが、記述されている現象と原因の関係から考えるに、他のアプリケーションでも同様の現象が発生すると思われます。

さてさて。

せっかく書いた文章を捨てるのがもったいないので(貧乏性)、邪魔かもしれませんが下に続けることにします。もし上のKBの内容がそれらしいようであれば、読み飛ばしてください。

========

私であれば、次の手順で調査を行います。

1. MAPファイル、CODファイル作成

「ワトソン博士のログを取得した際に実行していたEXEファイル」をビルドした際、一緒にMAPファイルやCODファイル(リスティングファイル)を作成していれば、そのファイルを用意しておきます。

もし作成していない場合は、「ワトソン博士のログを取得したEXEファイル」と、バイナリレベルで全く同じEXEファイル(バイト単位で比較すると、ファイルに埋め込まれたタイムスタンプ・チェックサム以外は一致する)が作成可能かどうか調べます。(ビルドに必要なソースファイルやビルドオプションに変更を加えていなければ作成可能です。)

作成可能であれば、コンパイルオプションに「リスティングファイルタイプ:マシン語コードとソースを含む」、リンクオプションに「MAPファイル作成」を追加してEXEを再作成してください。これで、「ワトソン博士のログを取得した際に実行していたEXEファイル」に対応するMAPファイルとCODファイルが得られます。

2. エラー発生行を特定

ワトソン博士のログがどれだけ取れているかにもよりますが、スタックダンプが含まれていればたいていエラー発生行を特定できます。

まず「フォールト->」が含まれる逆アセンブルリストを探します。次に、その下にある「スタックバックトレース」を探します。

スタックバックトレースを上から下に順にたどっていくと、そのうち「ReturnAd」(リターンアドレス)がアプリケーションのアドレス範囲(VC++6の標準オプション設定を変更していなければ0x00400000~)に入るところが出てきます。見つかったら、そのアドレスの直前にあるcall命令が例外を発生させたAPIを直接呼び出している場所です。

さて、仮にリターンアドレスが0x00401234だったとします。そうしたら、次はMAPファイルを見てこのアドレスがどの関数に属しているか探します。ちょうど0x00401234というアドレスは見つからないでしょうけれども、これに近いアドレスは見つかるはずです。そのアドレスに対応する関数名もMAPファイルにあります。

次はその関数名をCODファイルから探します。見つかったら、MAPファイルにあるアドレスがCODファイルにあるマシン語コードの先頭アドレスになるので、そこからリターンアドレス0x00401234に対応するはずの場所まで順番にアドレスを辿っていきます。関数の先頭アドレスが0x00401200であれば、0x34バイト先を探すわけです。

そうすると、その探した場所にある命令の直前の命令がcall命令になっているはずです。CODファイルには、その場所のC++ソースでの行番号とソース文もコメントとして入っているはずなので、あとは対応するソースをよーく見てエラーの見当をつけてください。

アセンブラの知識があれば、そこでcallを使った(他の関数を呼び出した)ときの引数の内容もある程度分かります。(ポインタ渡しだと、そのポインタの先の内容までは分かりませんが。)

3. 置き換え用EXEファイルと対応するMAPファイル作成

これ以降は将来への備えです。

コンパイルオプションでデバッグ情報を「プログラムデータベースを使用」、リスティングファイルタイプを「マシン語コードとソースを含む」、リンクオプションで「MAPファイルを作成する」、デバッグ情報「他の種類」を追加してビルドし、出来たEXEファイルを本番用として使用します。同時に作成されるMAPファイル、CODファイル、PDBファイルは保管しておきます。

MAPファイル、CODファイルの使い方は上記2.のとおりです。PDBファイルは、もし完全なクラッシュダンプが取得できればWinDbgを使って事後ソースレベルデバッグが可能になりデバッグ作業が非常に楽になるので、念のため取っておきます。

4. ワトソン博士のオプション変更

drwtsn32.exeを起動し、「クラッシュダンプファイルの作成」をチェックします。(デフォルトは、チェックが入っています。)

クラッシュダンプファイルとEXEとPDBがあればWinDbgで事後ソースレベルデバッグができます。(いわゆるポストモーテムデバッグです。UNIX系でコアダンプしたコアをデバッガで読み込んでデバッグするのと同じ種類のものです。)


普段何とも思わずに行っていることでも、文章にすると長いですね・・・

えーと、「どういうスキルを持った人に調査させればいいか」については、上記の内容を読んで『なるほど!』と言える人でしょうか。

参考URL:http://support.microsoft.com/kb/168006/ja

発生頻度が年2回というのはなかなか厳しい条件ですね。

さて・・・

「私であれば、次の手順で調査を行います。」という書き始めで延々とデバッグ方法を書いていたのですが、書き終わってからちょっとGoogleで検索したら、ひょっとするとちょうど質問者さんのトラブルと同じかもしれない現象がMicrosoftのKBにありました。

場所はここです: http://support.microsoft.com/kb/168006/ja

要点をかいつまんで書くと、MSVCRT/MFCのDLLのバージョン不整合でエラーが発生することがある、という内容です。KB...続きを読む

QVC++でDLL、エントリポイントが出来ない?

VisualStudio2010 VC++でDLLを作成し既存のDelphiXE2アプリで利用したいのですが
MSのサンプルソースそのままでDLLを作成しても、__stdcall;しても、Delphiの読み込み時に
「エントリポイントが見つかりません」と言われます。

http://msdn.microsoft.com/ja-jp/library/ms235636.aspx
ソースはMSのチュートリアルそのままです。

ためしに VS2010のツール dumpbin.exe /exports ????.dll と中身を覗くと
1 0 ooo11104 ?Add@MyMathFuncs@MathFuncs@@SGNNN@Z
2 1 ,,,,,,,,,,,,,,

のような表示とSummary 以下しか表示されずスタティックライブラリにしても中身は同じです。
それでは、と他のDLLをいくつか覗いてみましたが、大概のDLLやLIBファイルを覗くと
すっきりしたきれいな関数名の一覧がdumpbin /exports で表示されます。

では、DLLになっていないのかというと、作ったDLLを同じVC++でチュートリアル通りに
呼び出すと何の問題もなく使えますので、多分正常なのでしょう。 しかし、どうして
エントリポイントの一覧が見える形にならないのか分かりません。多言語で利用するには
必要かと思います。

VC++で作成したDLLやLibが他の環境で使えないとは考えられないので、なにか、常識的な
部分を知らないのだと思いますが、どなたかよろしくお願いします。

VisualStudio2010 VC++でDLLを作成し既存のDelphiXE2アプリで利用したいのですが
MSのサンプルソースそのままでDLLを作成しても、__stdcall;しても、Delphiの読み込み時に
「エントリポイントが見つかりません」と言われます。

http://msdn.microsoft.com/ja-jp/library/ms235636.aspx
ソースはMSのチュートリアルそのままです。

ためしに VS2010のツール dumpbin.exe /exports ????.dll と中身を覗くと
1 0 ooo11104 ?Add@MyMathFuncs@MathFuncs@@SGNNN@Z
2 1 ,,,,,,,,,,,,,,

のような表示とSummary ...続きを読む

Aベストアンサー

「DLL エクスポート DEFファイル」あたりで検索して下さい。
http://elksimple.web.fc2.com/memo/dll.html
とか見つかるかと思いますが……。

戻り値や引数の型、数によってdllexportでエクスポートした場合の名前が変わります。
dllimportならば、同じ形式でエクスポート名を生成しますから問題は出ないのですが……
他の環境で使う場合には使いにくいものになります。
extern "C"
とすることで、命名規則が微妙に変わりますが…やはり使いやすいものにはなりません。
defファイルで指定する方法ならば名前は固定化できます。
# ただし、この方法ではクラスは使えない…でしょう。

あと…
[技術者向] コンピューター > プログラミング > C・C++
のカテゴリの方がよろしいかと……。
# まぁ、使うりがDelphiでも、DLL作成はVCのようですし。

QC#で、C言語で作ったdllに文字列の参照渡し

Cで
int test(char* moji) {
  moji = "test";
  return 0;
}
のようなdllを作り、C#側から
  test(ref cs_moji);
としても変数cs_mojiに"test"という文字列は帰ってきませんでした。
数時間調べたりしてcs_mojiの型をstringやStringBuilder等としたのですが、どれもうまくいきませんでした。
ポインタのポインタを利用したときは文字列は帰ってきたものの文字化けがたくさんしていて理想とはかけ離れていました。
どのようにしたらCのdllからC#に文字列を送ることができるでしょうか。
初歩的な質問かもしれないですがよろしくお願いいたします。

Aベストアンサー

マネージドコードとアンマネージドコード間でのデータのやりとりになるので初歩的ではないです。

ひとまずこの辺は読んでおくべきかと思います。
http://msdn.microsoft.com/ja-jp/library/26thfadc%28v=vs.80%29.aspx
http://msdn.microsoft.com/ja-jp/library/e8w969hb%28v=vs.80%29.aspx


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング