NTT-X Store d払いご利用でdポイントが貯まる使える!

DLLが見つからない

VisualC++でDLLを明示的に読み出す学習をしています。

作ったプログラムを動かすと、自作したDLL「Dll1.dll」が
みつからないようです。
以下でret=126です。


SetLastError(0);
hMyLib = LoadLibrary(LPCWSTR("Dll1.dll"));
if (hMyLib==NULL))
    int ret = GetLastError();

Dll1.dllは、.exeと.slnと同じ場所におきました。
Dll1.dllはソリューションエクスプローラで表示されていましたが、赤いマーク(警告?)
がついていたので、「プロパティを開いてプロジェクトに含まれる」項目をFalseからTrueに
変えたところ、赤いマークが消えました。

さらに、何を設定しなおせばよいのでしょうか?

A 回答 (4件)

>エラーが4250に変わりました。


>(4250:このアプリケーションはアプリコンテキストでのみ実行できます)

https://www.reddit.com/r/learnprogramming/commen …
検索したらこんなのとか。
英語だけど……。

Dll1.dllの中身による…んでしょうかね。
上のURLのだと…Dllの中身はなんぞのクラスのようですが。
# C++のクラスをDLLとしてエクスポートできるのかは…私自身はやったことがないので不明です。

>これは一歩進んだということなのでしょうか?

「ファイルが見つからない」よりは進んだものと思われます。

>また、Dll1.dllは自分で作ったものですが、とあるアプリで提供しているDll2.dll
>にしたら、やはり126のままです。Dll1.dllでできたら、Dll2.dllを利用するフェーズに
>進みたいのですが。

こちらは不明。
    • good
    • 0
この回答へのお礼

本当にいろいろありがとうございました。
気を取り直して、試しにもう少しまともと思えるDll3.dllをロードしたところ
エラーがなくなっていました。

ということは、今まで試していたDllがよくなかったと考えられます。
Dll2.dllが使えないと困るのですが。

とにかくお付き合いくださり、大変感謝いたします。

お礼日時:2017/09/15 09:57

>調べたところ、文字列のキャストが関係ありそうでした。



ええっと……
>LoadLibrary(LPCWSTR("Dll1.dll"));
の書き方は確かに変ですね…。

コンパイラの設定での文字セットの変更に対応したいのであれば、
_T("Dll1.dll")
とか
_TEXT("Dll1.dll")
とかでよいのではないでしょうか?

https://msdn.microsoft.com/ja-jp/library/windows …(v=vs.85).aspx
_TEXTではなくTEXT()か?
    • good
    • 0
この回答へのお礼

長くお付き合いいただき、大変感謝です。

文字セットについては私には難しいのですが、
とりあえず、プロパティの文字セットをマルチに変更し、_T(Dll1.dll")としてみたら、
エラーが4250に変わりました。
(4250:このアプリケーションはアプリコンテキストでのみ実行できます)

これは一歩進んだということなのでしょうか?
また、Dll1.dllは自分で作ったものですが、とあるアプリで提供しているDll2.dll
にしたら、やはり126のままです。Dll1.dllでできたら、Dll2.dllを利用するフェーズに
進みたいのですが。

お礼日時:2017/09/14 17:39

>フルパスで書くのはソースでよかったですか?



LoadLibrary()で指定しているファイル名…ですね。
# 言うまでもないことですが、パス区切りの円マークはエスケープして下さいね。
# '/'にしておく…という手もありますけど。

>プロパティなど変える必要があるのでしょうか。

については……

>Dll1.dllはソリューションエクスプローラで表示されていましたが、赤いマーク(警告?)
>がついていたので、「プロパティを開いてプロジェクトに含まれる」項目をFalseからTrueに
>変えたところ、赤いマークが消えました。

というのが状況不明ですのでなんとも…。
該当プロジェクトにDLLを追加…とかそういう操作は不要かと思われますけど。
# C#などで利用する…とかだと必要かも知れません。C++/CLIでも必要なんでしょうかねぇ……。
    • good
    • 0
この回答へのお礼

再度、ありがとうございます。
フルパスで \\も/も使ってみましたが、ダメでした。

調べたところ、文字列のキャストが関係ありそうでした。
それだけが原因ではないかもしれませんが
文字列のキャストについてもう少し勉強してみます。

赤いマーク云々は、イチから作り直したところ
ソリューションエクスプローラからDLLが消えてしまったので
なかったことにします。いろいろいじりすぎて変なことをしたせいかもしれません。

もうしばらく締め切らないので、何かヒントがあったら教えてください。

お礼日時:2017/09/14 16:53

>作ったプログラムを動かすと、自作したDLL「Dll1.dll」が


>みつからないようです。

勉強/実験ってことならDLLファイルの場所はフルパスで指定したらどうでしょうか?
一応、LoadLibrary()でカレントディレクトリも探すとは思いますが……。

「exeと同じディレクトリに置く」という場合でも、カレントディレクトリからではなく
実行ファイルのフルパス名を取得してから文字列操作でフルパス指定にした方がよろしいかと。
# カレントディレクトリについては操作によって意図しないまま変わっている場合がありますので。
    • good
    • 0
この回答へのお礼

またまたありがとうございます。
フルパスで書いてみたのですが、状況変わらずです。

フルパスで書くのはソースでよかったですか?
プロパティなど変える必要があるのでしょうか。

または、自作のDLLがよくないとか?(かなり簡単なものですし、
まだ関数を読んでいないですよね)

お礼日時:2017/09/14 14:04

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

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

QDLLの明示的な呼び出し

DLLを実行中(run time)で呼び出す練習で以下のプログラムを書きました。
Visual C++ 2012です。
以下でビルドすると
'HINSTANCE' : 定義されていない識別子です。 というエラーメッセージがでます。
そこで、#include <DxLib.h>が必要だとどこかに書いてあったので入れてみると

'#include <DxLib.h>': プリコンパイル済みヘッダーの使用を検索中にスキップされました
とういエラーメッセージとなります。

実際、PC内でDxLib.hを検索しても見つからないのですが
これを動かす、またはDLLを呼び出すにはどうしたらよいのでしょうか?

#include <stdafx.h>
//#include <DxLib.h>

#define STRICT
int function1();

int _tmain(int argc, _TCHAR* argv[])
{
function1();
}


int function1()
{
HINSTANCE hMyLib;
PTESTFUNC fpTestFunc;

hMyLib = LoadLibrary( "dll1.dll");
if (hMyLib) {
fpTestFunc = (PTESTFUNC)GetProcAddress(hMyLib, "TestFunc");
for (int i = 0; i <=9000; i++) {
int x = (*fpTestFunc)(i, i + 10);
printf("result = %d,%d,%d\n", i , i + 10, x);
}
}
FreeLibrary(hMyLib);
break;

}

DLLを実行中(run time)で呼び出す練習で以下のプログラムを書きました。
Visual C++ 2012です。
以下でビルドすると
'HINSTANCE' : 定義されていない識別子です。 というエラーメッセージがでます。
そこで、#include <DxLib.h>が必要だとどこかに書いてあったので入れてみると

'#include <DxLib.h>': プリコンパイル済みヘッダーの使用を検索中にスキップされました
とういエラーメッセージとなります。

実際、PC内でDxLib.hを検索しても見つからないのですが
これを動かす、またはDLLを呼び出す...続きを読む

Aベストアンサー

>私は単にDLLの利用法を学習中なだけなのですが、

なら、DxLibは関係ありません。

>windows.hから入るとは?何が何に入ったのでしょうか?
>(とぼけた質問のようですみません)
>また、何を記述することになるのでしょうか?

windows.h内、またはwindows.hからインクルードされているヘッダ内にHINSTANCEの定義があります。

stdafx.hのヘッダ内にwindiws.hのインクルードを追加して下さい。
ただし、VS2012辺りになると
#include <windiws.h>
だけで済むかどうかは判りません。
他にもdefine定義が必要になるかも知れません。

Qプログラムの改良

人の作ったプログラムを改良することになりました。
Visual C++ は初めてですが、CやC++は一通り勉強しています。

そこで、いろいろ調べているのですが、
例えば
「MFCは使わずに,Win32API SDKを用いた方法」
などという説明があります。

自分が対応しているプログラムが、そのどちらであるか、あるいはほかの方法で作られているか
というのはどうしたら分かるのでしょうか?

Aベストアンサー

No1です
私はC++は全然触ったこと無いので
あまり的確な回答は期待しないでくださいね

Q1.いいんじゃないでしょうか?
MSDNのOnPoint↓
https://msdn.microsoft.com/ja-jp/library/01c9aaty.aspx

OnPointクラス(Cwndクラス)
https://msdn.microsoft.com/ja-jp/library/1xb05f0h.aspx
このページの一番最初に
「Microsoft Foundation Class ライブラリにあるすべてのウィンドウ クラスの基本機能が用意されています。」と書いてありますから
そういうことですね

Q2.なんでもいいと思いますけど
そもそもあなたが対応するプログラムが
きちんとWin32のみで、もしくはMFCのみで書かれているとは限らないですからね
適当に作られて、両方が混在している可能性だってありますし

Q3.そこからですか
そこは調べればすぐ出てくるかと思いますが
MFCというのはWin32をラッピングしたものです

Q4.作った本人に聞く
仕様書とかがあるならそれを見る

No1です
私はC++は全然触ったこと無いので
あまり的確な回答は期待しないでくださいね

Q1.いいんじゃないでしょうか?
MSDNのOnPoint↓
https://msdn.microsoft.com/ja-jp/library/01c9aaty.aspx

OnPointクラス(Cwndクラス)
https://msdn.microsoft.com/ja-jp/library/1xb05f0h.aspx
このページの一番最初に
「Microsoft Foundation Class ライブラリにあるすべてのウィンドウ クラスの基本機能が用意されています。」と書いてありますから
そういうことですね

Q2.なんでもいいと思いますけど
そもそもあなたが...続きを読む

Qプログラミング

プログラミングを学びたいんですが最初にある程度プログラミングができるようになってからアルゴリズム論を学ぶ方がいいですか?それとも最初にアルゴリズム論を学んだ方がいいですか?

Aベストアンサー

何の言語か知りませんが、最初に、アルゴリズムなどに手をつけたら、闇の中だと思いますね。よく、構文と勘違いしている人がいますね。

アルゴリズムの定義をどういうように解釈しているのか分かりませんが、アルゴリズムはコンピュータやプログラミング言語に依存しません。一般的な定義は「問題を解くための論理または手順」のこと。また、コンピュータのプログラミング向きでもないものも存在します。

一度は、丁寧に勉強しましたが、私は、ほとんどアルゴリズムは分かっていません。たぶん、古典的なものは、コンピュータのない時代に数学の天才が作ったものだと思いますが、囲碁や将棋の定石のような解釈しかしていません。VBAなどでは、アルゴリズムを使った人など、年に一度、現れるかどうかですね。理由は、.NetFrameWork などの関数に、すでに包合されているからです。

ここのサイトの下に代表的なアルゴリズムの名称が出ています。

http://e-words.jp/w/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0.html

何の言語か知りませんが、最初に、アルゴリズムなどに手をつけたら、闇の中だと思いますね。よく、構文と勘違いしている人がいますね。

アルゴリズムの定義をどういうように解釈しているのか分かりませんが、アルゴリズムはコンピュータやプログラミング言語に依存しません。一般的な定義は「問題を解くための論理または手順」のこと。また、コンピュータのプログラミング向きでもないものも存在します。

一度は、丁寧に勉強しましたが、私は、ほとんどアルゴリズムは分かっていません。たぶん、古典的なものは...続きを読む

QC++を学ぶためにCの知識は必須ですか?

将来の就職と個人的興味のため、C++を勉強しようと思ったんですが(C++にはオブヘクト志向があるため)ネットでいろいろ調べていると「Cが基盤になっているためCから勉強を始めたほうがいい」とありました。
正確にはどこまでの知識と経験が必要ですか?
そもそもC++を学ぶためにCの知識は必須ですか?

Aベストアンサー

まあ、Cの言語仕様を一通り軽くやっといた方が良いかも。
ポインター、配列、構造体、整数演算、型の表記の仕方とかは
結構癖があるから、事前に知っといた方が良いでしょう。

Cの言語仕様ってC++に比べて驚くほど小さいので
そんなに時間はかからないと思う。
最初からクラスも大変だし、最初はベターCから
始めるのも良いのでは。

しかし就職にC++が役立つかというと、確かに
c++使いまくりのシステムもあるが
Javaの方が圧倒的に有利というのは
覚えておいた方が良いでしょう。

QCのプログラムに無性にイライラするのはおかしいですか?

CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
 for( y =0; y < Y; y++ ){
  for( x = 0; x < X; x++){
   p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
   if(p[0]==i){hn[i]++;}
  }
 }
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?

なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++){
  p[0] = img -> imageData[img->widthStep* y + x*3 ];  //B(青色)
  hn[ p[0] ]++;
 }
}

3重にするならせめて、y,x,i の順にしてp[0]への代入は1回で済ませればと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++){
  p[0] = img -> imageData[img->widthStep* y + x*3 ];  //B(青色)
  for( i=0; i<256; i++){
     if(p[0]==i){hn[i]++;}
  }
 }
}

最近のコンパイラの最適化では、私の書いたようなコーディング(修正?)は無意味なのでしょうか?

CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
 for( y =0; y < Y; y++ ){
  for( x = 0; x < X; x++){
   p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
   if(p[0]==i){hn[i]++;}
  }
 }
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?

なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++)...続きを読む

Aベストアンサー

利点を考えてみました


これを並列処理したときに
スレッド0: hn[0] に p[0] = 0 をカウント
スレッド1: hn[1] に p[0] = 1 をカウント
...
とすれば、
・img -> imageData は読み出すだけなので衝突しない
・hn[i] でアクセスする領域は、スレッド毎に i が違うので、同じ箇所に書き込まれることはない。
となり、排他処理が不要となります。
(もちろん、x,y,i,p[0]はスレッドでローカルな変数とします)

ただ、並列処理のオーバーヘッドや同時並列処理数等を考えると、こんな並列処理はしない方が効率的です。


あるいは、hn[]がシークに時間がかかる領域の場合、
hn[p[0]) で毎回違う位置を探しに行って、その時間が無視できないほどだったら、
先にhnを決めてしまった方が速くなるでしょう。

こちらも、非現実的です。

QC#プログラミング、少数の取り扱い方がわかりません

説明のしかたが下手で申し訳ないのですが

double型の数値で0.999999999999......と続く数値があったとして、この数値が1.0として扱われるのは小数第何位からですか?

また、1.0に近似してほしくないときはどうしたらいいですか?
C#でプログラミングをしています

Aベストアンサー

やろうとしていることは
lim_(x→0) f(x) = 1
で、 xを0に近付けつつ、f(x) を計算する、という感じなのでしょうか。


方法は3つあります。
(1) 計算式を工夫する。
0.999... だと 10^-15程度までしか正しくありませんが
0.000 .... 1 → 1.0 * 10^-n だと、10^-nの桁から15桁程度までの精度があります。
式を工夫して、計算結果が1ではなく、0に向うようにすることで、精度よく計算できるかもしれません
例)
g(x)=1-f(x) を求める。 ※「桁落ち」に注意


(2)十分な精度のある型を使う
https://ja.wikipedia.org/wiki/%E4%BB%BB%E6%84%8F%E7%B2%BE%E5%BA%A6%E6%BC%94%E7%AE%97
自作するか、既存のものを使う


(3)計算自体に意味があるのか、考えてみる。

QC言語 構造体の中に共用体を定義した変数の初期化に関して

C言語のコンパイルエラーに関する質問です。
以下のような構造体の中に共用体を作成して、constで初期値を入れておきたいと考えています。
機械に適用する初期パラメータのような感じです。
「初期化子が多すぎます。」というコンパイルエラーがでるのですが、どこが多いのかわかりません。
どう修正すれば良のか教えていただけないでしょうか?

// 構造体定義
typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t xxxx;
Uint16_t zzzz;
}PrgPatternA_t;

typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t yyyy;
}PrgPatternB_t;

typedef struct {
Uint8_t pattern;
union {
PrgPatternA_t param_a[3];
PrgPatternB_t param_b[2];
}param;
} Program_t;

// 変数定義
EsCourseProgram_t ES_COURSE_PROG_DATA = {
PATTERN_A,
{ // Aパターン
// time mode xxxx yyyy
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50}
}
}

C言語のコンパイルエラーに関する質問です。
以下のような構造体の中に共用体を作成して、constで初期値を入れておきたいと考えています。
機械に適用する初期パラメータのような感じです。
「初期化子が多すぎます。」というコンパイルエラーがでるのですが、どこが多いのかわかりません。
どう修正すれば良のか教えていただけないでしょうか?

// 構造体定義
typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t xxxx;
Uint16_t zzzz;
}PrgPatternA_t;

typedef struct {
Uint16_t ti...続きを読む

Aベストアンサー

どの初期値がどのメンバーに対応するかをじっと見ていくと, {} が 1つ足らない. つまり初期化子は
{
PATTERN_A,
{ // Aパターン
// time mode xxxx yyyy
{
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50}
}
}
}
でないといけない.

どこかの {} を忘れていたんだと思う. 共用体を初期化するときの {} かなぁ?

QC言語について(三角形の面積・double型)

現在C言語を勉強中のものです。
以下のプログラムを実行すると、面積の計算結果が0になってしまいます。
doubleを全てintに、%fを全て%dにするとうまく動くのは確認したのですが、
自分が作りたいのは、引数をdoubleにし、実行結果も小数点込みで計算するものです。

以下のプログラムの問題点とその理由、またどのように書き換えることでうまく動くのかを教えていただけたらと思います。
よろしくお願いいたします。

~~以下コード~~
#include <stdio.h>

double tri(double,double);

int main(){
   double takasa,teihen;
   double menseki;
   printf("takasa=");
   scanf("%f",&takasa);
   printf("teihen=");
   scanf("%f",&teihen);
   menseki = tri(takasa,teihen);
   printf("menseki = %f",menseki);
}

double tri(double n1,double n2){
   return n1*n2/2;
}

~~以下実行結果~~
takasa=3
teihen=4
menseki = 0.000000

現在C言語を勉強中のものです。
以下のプログラムを実行すると、面積の計算結果が0になってしまいます。
doubleを全てintに、%fを全て%dにするとうまく動くのは確認したのですが、
自分が作りたいのは、引数をdoubleにし、実行結果も小数点込みで計算するものです。

以下のプログラムの問題点とその理由、またどのように書き換えることでうまく動くのかを教えていただけたらと思います。
よろしくお願いいたします。

~~以下コード~~
#include <stdio.h>

double tri(double,double);

int mai...続きを読む

Aベストアンサー

doubleのフォーマット指定子は%fではなく%lfです
とりあえずそこを変えてみて実行してみてください

QC言語について質問お願いします まだ勉強中なのでご指導よろしくお願いします str1=big str

C言語について質問お願いします

まだ勉強中なのでご指導よろしくお願いします

str1=big
str2=city
str3=bigcity

という結果にしたいのですが下のような結果になり困っております(´;Д;`)

もっといい書き方もあるかもしれませんが、今書いてあるコードを活かして訂正して結果通りになるにはどうすればいいでしょうか?!

その他アドバイスありましたら先輩方よろしくお願いしますm(_ _)m

Aベストアンサー

一つ訂正します
誤) char str1[4]={"big"},str2[4]={"city"}, str3[1]={0};
正) char str1[4]={"big"},str2[5]={"city"}, str3[1]={0};

ベテランでもこういう単純な間違いをすることがあります。
間違えもいいんです。それに気付いて直せれば。

ダメなときは、どこでダメになっているかを調べ、何故ダメになるかを調べ、どうすればダメじゃなくなるかを考えます。
これはベテランでも初心者でも変わりません。



原因は str3[1],str3[2] ...と範囲外に書き込んだことです。
例えるなら、「子供に紙とクレヨン渡したら、調子にのって床にまで絵を描いてしまった」状態です。
よって、対策は
・これらに書きこまないようにする。つまり、配列に収まる大きさの文字列にする
 (例えるなら「紙の外に描かないような小さな絵にする」)
・これらが書き込まれても問題ない状態にする。つまり、配列の大きさを十分に大きくする
 (例えるなら「絵が入るくらいの大きな紙にする」)
のどちらか、となります。

今回の場合、書き込みたい文字列が決まっているので、前者の「収まる文字列にする」という方法は使えません。
よって、後者の「文字列が収まる配列にする」が正解になります。

配列の大きさの指定方法はわかりますね?

一つ訂正します
誤) char str1[4]={"big"},str2[4]={"city"}, str3[1]={0};
正) char str1[4]={"big"},str2[5]={"city"}, str3[1]={0};

ベテランでもこういう単純な間違いをすることがあります。
間違えもいいんです。それに気付いて直せれば。

ダメなときは、どこでダメになっているかを調べ、何故ダメになるかを調べ、どうすればダメじゃなくなるかを考えます。
これはベテランでも初心者でも変わりません。



原因は str3[1],str3[2] ...と範囲外に書き込んだことです。
例えるなら、「子供に紙とクレヨン渡...続きを読む

QC言語 型変換のタイミング

C言語 型変換のタイミングについて教えてください。
「型変換は代入のとき行われる」と理解していたのですが、代入の前の計算時も行われるのでしょうか?

char c1=120,c2=10;
int i;
のとき、
i = c1 + c2;
は i= -126 を期待したのですが i = 130 となっていました。

質問1)これは、C言語の仕様でしょうか? それともコンパイラに任されている仕様でしょうか?

関連して、
質問2)期待した計算結果をiに代入するには、
char c3;
c3 = c1 + c2; i=c3;
とする以外に方法ありますか?

質問3)計算途中でオーバーフローする可能性のある計算を確実の行うにはどのように記述したらよいでしょう?
int x0,x1,x2,x3;
x0 = (x1 + x2 + x3) / 3;
x0 = x1 * x2 / x3; (ただしx2 < x3)

よろしくお願いします。

Aベストアンサー

1 については C の仕様です. 計算を行うときに, int 以下の型はすべて int (または unsigned int) に変換したうえで計算されます. したがって
i = c1 + c2;
はあたかも
i = (int)c1 + (int)c2;
と書いたのと同じ計算をします.

2 は
i = (char)(c1+c2);
のように演算結果を強引にキャストすればいい, んじゃないかなと思う.

3 については.... ポータブルにやるなら努力と根性で多倍長演算を実装するしかないんじゃないかなぁ.

あ, あと余談だけど C の仕様では
char は*少なくとも*8ビット
です.


人気Q&Aランキング