• ベストアンサー

[VisualStudio]コンソールではリンクOKなのに、WinAPIでリンクNG

はじめまして。 今、VisualStudio2005でC++であるDLLをリンクして使用しようとしています。(もらったライブラリでブラックボックスです。⇒仮にsample.dll) sample.libをVisualStudioのプロパティでリンク設定して sample.libに含まれるinitialize()APIを呼びます。 initialize()の内部では (1)ファイル読み込み (2)読み込んだ情報から何かしらの処理 と流れるようです。 そこでコンソールで使用した場合には、きちんと動作するのですが Winアプリで作成して同じ処理をした場合には、処理が落ちます。 Winアプリで作成した場合の感触的には、 (1)までは動いて(2)で落ちます。 内部の処理が悪いのかもしれませんが、そもそも、コンソールとWinAPIで、リンク方法など異なる部分というのがありますでしょうか? 情報が少ないかもしれませんが、詳細とまでは言わず、一般論で構いません。 詳しい方がおりましたら、ご教授いただければと思います。 イメージ的には以下のとおりです。 コンソール: int main() { initialize(); return 0; } Win32: int APIENTRY _tWinMain(...) { initialize(); return 0; }

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス ・コンパイル時の文字コードはどうなっていますか?  コンソールで正しく動き、Win32ではエラーになるなら  コンパイル時の文字コードセットを『マルチバイト文字』に  オプションから設定します。 ・VC2005から『Unicode文字セットを使う』が初期値に変わりました。  私の推測ですがもらった DLL はマルチバイト文字コードを  処理するようになっていると思います。 ・あと DLL が Unicode 文字セットにも対応していますか?  対応していた場合は別の原因になりそうです。  その場合には補足をお願いします。

goopon
質問者

補足

アドバイスありがとうございます。 文字コードは最初からマルチバイトでやっててNGでした。 試しにunicodeにしたら動きが変わりました。 処理落ちしていたものがエラーが返るように変わりました。 結局内部の問題ですかね。。。 問題は解決しませんが、少なからず関係してそうですね。 一般的な知識としても勉強になりました。

その他の回答 (1)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

リンクの問題ではないと思います。 >initialize()の内部では >(1)ファイル読み込み >(2)読み込んだ情報から何かしらの処理 >と流れるようです。 ということですから、カレントディレクトリが異なっていて、ファイルの読み込みに失敗しているとかかなあという気がしますけど。 あと、そのDLLにバグがあって、コンソールではたまたま動いただけとかも考えられなくもないですね。 そのDLLってどの程度実績のあるものなんでしょうか?

goopon
質問者

補足

DLLはコンソールのみで実績あります。 (1)のファイルのフォーマットまでは見てるようなので、ディレクトリには間違いなさそうなのですが。。。 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

  • Win32アプリでコンソール出力するには?

    VisualStudio.Netを使って、Win32のGUIアプリをつくっているのですが、デバッグするときにprintfなどを使いたいのです。 この出力をコンソールなどに出力するにはどうすればよいのでしょうか?教えてください。

  • windows10visualstudio2010

    windows10でvisualstudio2010を使って、.net4のアプリを作成しています。 win10には.NET Framework 4.7.2がはいってますが、デバッグした場合、.net4で動作することになりますか?

  • エントリポイントがDLLから見つからない

    WIN2000のVC++6.0を使ってWin32DLLを作成して、VBから呼びたいのですが、「エントリ関数がDLLファイル内に見つからない」言われるので、ためしにVCから呼んでみたのですが、表題のようなエラーになります。内容は入門書のサンプル通りに作ってみたのですが・・・ちゃんとEXPORTされていないのでしょうか? [DLL側] <ヘッダファイル> #ifdef XXXX_EXPORTS #define XXXX_API __declspec(dllexport) #else #define XXXX_API __declspec(dllimport) #endif XXXX_API long AddLong(long a, long b); <ソースファイル> XXXX_API long AddLong(long a, long b) { return a + b; } [呼び出し側VC] #include "stdafx.h" #include "XXXX.h" int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { TCHAR s[20]; wsprintf(s,"%d",AddLong(123,456)); MessageBox(NULL,s,"DLLの参照",MB_OK); return 0; } プロジェクトの設定のリンク時のライブラリには XXXX.lib を追加しました。 初めてのDLL作成でよく分かりません。

  • VisualStudio2008の最適化について

    VisualStudio2008の最適化について こんにちは。 質問させてください。 現在VisualStudioでとある処理を書きました。 わかりやすく以下のコードを書いたとします。 #include <stdio.h> #include <windows.h> #pragma comment ( lib, "winmm" ) int main() {   DWORD t = timeGetTime();   int sum=0;   int i=0;   for( i=0;i<0x7fffffff;++i )     ++sum;   t = timeGetTime() - t;   printf( "time -> %d\n", t );   return 0; } 今回は単純にfor文の時間を計測したいとします。 上記コードをReleaseモード実行速度重視 (/O2)でコンパイルし、実行すると出力は必ず time -> 0 と出力されます。 上記コードをReleaseモード実行速度重視 (/O2)でコンパイルしアセンブリとして出力したものです。 CONSTSEGMENT ??_C@_0M@DAGCMHCE@time?5?9?$DO?5?$CFd?6?$AA@ DB 'time -> %d', 0aH, 00H ; `string' push esi mov esi, DWORD PTR __imp__timeGetTime@0 push edi call esi mov edi, eax call esi sub eax, edi push eax push OFFSET ??_C@_0M@DAGCMHCE@time?5?9?$DO?5?$CFd?6?$AA@ call DWORD PTR __imp__printf add esp, 8 pop edi xor eax, eax pop esi ret 0 アセンブリコードを見るとするとint sumはコード中でインクリメントされるだけで他に使用されないので、最適化によって削除されてしまっているようです。 この、時間を計測したいところだけ適度に最適化させつつ、処理が残るようにするような命令はありませんでしょうか? pragmaでかこったりするだけで処理が消されない程度に最適化されるとうれしいのですが・・・ よろしくお願いします。 /*   VisualaStudio 2008 academic Edition   今回のテストケースではsumの値もコンソールに出力すれば最適化で消されずに済むのですが最適化の計算によってforループは削除され、代わりに即値(0x7fffffff)がそのまま表示されるように最適化されてしまいます。   ですので今回は   ・使用した変数を使用するように書き換える   ・最適化で消されないようにコードを記述しなおす   ・inlineアセンブラで最適化させない   といった解決策以外でよろしくお願いします。 */

  • コンソールからのメッセージボックスをアクティブに

    Win32APIについて教えてください。 #include <iostream> #include <windows.h> int main() {   int i=0;   char mes[20]; // std::cin >> i;   std::sprintf(mes, "%dが入力されました", i);   MessageBox(NULL, mes, "test", MB_OK);   return 0; } をコンソールから実行するとメッセージボックスがアクティブになるのですが、コメントの部分を外してコンソールからの入力を受け取ると、コンソールがアクティブになってメッセージボックスがコンソールの下に隠れてしまいます。メッセージボックスをアクティブにすることはできるのでしょうか。 宜しくお願いします(WinXP、bcc32を使用しています)。

  • VC++でコンソールアプリのパスの対応の問題

    今、VC++でコンソールアプリをやっていますが、アプリのイメージとして sample.exe -f C:\a.txt -d のコマンドで、C:\a.txtのファイルを削除し、 sample.exe -f C:\a.txt -s で、ファイルをコンソールに表示するようにしたいですが、問題は指定されたパスの問題ですが、内部でファイルのfopenとか、removeとは、C:\\a.txtしないといけないようですが、 コマンドから入力したパスに対する処理は、どうすればよろしいでしょうか?よろしくお願いします。

  • VisualStudio.netのC++でC言語の勉強をしたいです

    VisualStudio.netのC++でC言語の勉強をしようと思っているのですが C言語のコンパイルの仕方がわかりません。 新規プロジェクト>>WIN32>>win32コンソールプロジェクト でプロジェクトを開きソースを書いてビルドしてみると エラー出てしまいました。 「fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。」 ソースは以下のとおりです。 #include <stdio.h> void hello(void); void hello(void) { printf("hello"); return; } int main(void) { hello(); return 0; } C言語をコンパイルする方法に間違ったことをしているのでしょうか? それともソースのバグなのでしょうか? 初心者質問ですがよろしくお願いいたhします。

  • DLLが LoadLibrary() でロードされたか判断できますか

    VC++6.0でDLLを作成しています。 アプリケーションが自分のDLLを LoadLibrary()でロードしたのか、 LIBリンクでロードしたのか、判断はできるでしょうか。 DLLの処理の中で、LoadLibrary()でロードされた場合と LIBリンクでロードされた場合の処理を分けたいのが目的です。 (LIBリンクの場合、デタッチ時にはメインのスレッドしか動作しないため) <補足> 正式にはどう呼ばれているか解らないのですが、「LIBリンク」は VCの設定でリンクするLIBを指定し、アプリケーションでは DLLが提供する関数名を記述する方法を意味します。

  • DLLでグローバル変数の確保方法

    Visual c++ 2008 express edition を使い、mt4(為替取引用標準的トレードツール)用のDLLを作ろうとしています。 DLLのプログラムもvc2008も初めて(普段はBCB6でwindowアプリに使っている)なのでよく見えないところがあります。 サンプルプログラムを参考に、func_openで書き込みファイルをopenし、そのあとイベントが発生するたびに、func_putが呼ばれ、ファイルに蓄積し、何日か連続して運転後、func_closeが呼ばれ、ファイルをクローズする処理を下記サンプルとして試しています。 よく見えないことは、DLLなので、MT4プログラムと一緒にコンパイルリンクをすることはできませんので(当然ですが)、処理に必要な多くのメモリ領域を、運転中保持しておく方法が、見えないことの眼目です。 この例の場合は、ファイルポインターfpwを保持しておくために、第1行目のstatic宣言をしました。とりあえずfunc_putを1回呼ぶだけの処理を試したところ、正しくファイルには書き込まれていました。 他にmalloc関数などを使う方法もあろうかと思いますが、本例のようにグローバル変数で確保、保持できれば、見通しがよくなりますので、問題なければこの方法を採用したいのです。 他の条件として、このDLL関数群は、異なるMT4あるいは、MT4内の複数のプロセス(?)から呼ばれることはありません。  そこで、お聞きしたいことは、static宣言で、メモリーリーク(開放されずに残る)や、意図しないstaticでない状態(内容が破壊される)などの問題がでないでしょうかということです。ようするに正しい使い方でしょうかがよくわからないのです。 サンプルコード static FILE *fpw; // この記述で不都合がないか? BOOL APIENTRY DllMain(HANDLE hModule, DWORD........) { switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH; ....... return(TRUE); } MT4_EXPFUNC int __stdcall func_open(const int ipar) { fpw=fopen("c:\\fx\\log.txt","w"); return(1); } MT4_EXPFUNC int __stdcall func_put(const int val) { fprintf(fpw,"static=%d",val); // その他いろんな処理 return(0); } MT4_EXPFUNC int __stdcall func_close(void) { fclose(fpw); return(0); }

専門家に質問してみよう