一括表示

VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 

The value of ESP was not properly saved across a function call.が出てうまくいきません。
VS2013VC++ で Hamlog50.dllを使ってHamlogの操作をしたいのです。
アクセスに必要なHamlog50.Libも作成し関数にはextern "C" __declspec(dllexport) 及びextern "C" __declspec(dllimport)を付け
DLL作成時も含めて__cdecl(/Gd) オプション(標準)で行っています。
これで名前修飾もなくビルドはエラーがでず完了します。
ところが、デバッグを行うとHamlog50.dllを呼び出す関数のところでこの警告が出てしまいます。 GetThdllVersion()等の様に引数の無いものは大丈夫なようですが(当たり前ですか)、SetDbsShare_VC(0)と単純なものでも発生します。
一方やむなく、 LoadLibrary(L"Hamlog50.dll")
GetProcAddress(hDLL, "HamlogOpen")
などからコールする方法では問題なくアクセス出来ることも確認しています。何か解決策がありそうなんですが。この辺の処うまく切り抜けておられる方アドバイスお願いいたします。
C++側の呼び出し規約を __stdcall (/Gz) に変更すると良いとの情報も得ていますが、名前修飾の問題が解決出来ませんでした。

2014/09/27(Sat) 07:51:26  [No.574]


Re: VC++ Run-Time Check Failure #0 投稿者:JA2BQX 太田 

こんにちは。
VB2010を常用なのでC関係は分からないので難しい事は分かりませんが、
確か Hamlog50.dll や THDLL2VB.DLL は  .NET Framework は 3.5 で無いと一部に不具合があるような...。

3.5以外でお使いなら .NET Framework3.5 で試して下さい。 

2014/09/27(Sat) 10:43:07  [No.575]


Re: VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 

> 確か Hamlog50.dll や THDLL2VB.DLL は  .NET Framework は 3.5 で無いと一部に不具合があるような...。
>
> 3.5以外でお使いなら .NET Framework3.5 で試して下さい。 
.NET Frameworkはあまり意識しないでやっていますが、関係あるのですかね。色々勉強中です。
 C++系はポインターを自由に使えるので便利なんですが。バグも出やすいのですね。DLLの動的リンクとかの手法で何とか動きそうなのですが、何かスマートでない気がするのと、何か問題がありそうで気分が良くないのですね。あるとき突然一致も察知も動かなくなるような。VC++でチャレンジされた方があれば意見が聞きたいのですが。私だけの問題なのか(これなら、何か別の原因が関係していそうなので、調べなおさないといけないし)、同じ内容が出て回避されたのか。
 趣味でやっていますから、気長にやっていきます。太田さんまた相談に乗ってください。

2014/09/27(Sat) 21:36:08  [No.576]


Re: VC++ Run-Time Check Failure #0 投稿者:JG1MOU浜田 

>  C++系はポインターを自由に使えるので便利なんですが。バグも出やすいのですね。DLLの動的リンクとかの手法で何とか動きそうなのですが、何かスマートでない気がするのと、何か問題がありそうで気分が良くないのですね。

Hamlog50.dllは昔ながらのShift-JISで、VC++はUnicode という違いが
あるかと思いますが、その辺の型の宣言やキャストをうっかりすると、
バグってしまうかと思います。
まぁ、それは十分にご承知のことと思いますが。

動的リンクならOKということは、インポートLIBに問題ありでしょうか。
なお、関数の型は、__cdeclではなく__stdcallで宣言してます。
確か、Borland C++では、
#define WINAPI __stdcall  だったような。。。

スタックに渡す順序が逆になるのでしょうね。

ちなみに、私の場合、VC++は大昔のVC++ 5.0使ってます。Hi

こんな宣言になってますが。。。Borland C++ 5.0
int WINAPI __export HamlogOpen( 
  int WINAPI (* func)(char *), // NULLでOK
  TThLog *,
  const char *, // HAMLOG.MST
  const int)

2014/09/29(Mon) 21:52:20  [No.577]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

銅子OM

JO1SIMでしまです。

浜田OMのフォローが、まさにそのことでした。


浜田OM> #define WINAPI __stdcall  だったような。。。

ただ、動的によびだしたとしても、この辺のキャストを誤ると動かないはずではあったと思いますが。(謎)

失礼しました。


> >  C++系はポインターを自由に使えるので便利なんですが。バグも出やすいのですね。DLLの動的リンクとかの手法で何とか動きそうなのですが、何かスマートでない気がするのと、何か問題がありそうで気分が良くないのですね。
>
> Hamlog50.dllは昔ながらのShift-JISで、VC++はUnicode という違いが
> あるかと思いますが、その辺の型の宣言やキャストをうっかりすると、
> バグってしまうかと思います。
> まぁ、それは十分にご承知のことと思いますが。
>
> 動的リンクならOKということは、インポートLIBに問題ありでしょうか。
> なお、関数の型は、__cdeclではなく__stdcallで宣言してます。
> 確か、Borland C++では、
> #define WINAPI __stdcall  だったような。。。
>
> スタックに渡す順序が逆になるのでしょうね。
>
> ちなみに、私の場合、VC++は大昔のVC++ 5.0使ってます。Hi
>
> こんな宣言になってますが。。。Borland C++ 5.0
> int WINAPI __export HamlogOpen( 
>   int WINAPI (* func)(char *), // NULLでOK
>   TThLog *,
>   const char *, // HAMLOG.MST
>   const int)

2014/09/30(Tue) 21:45:26  [No.579]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

銅子OM

JO1SIM出島です。
CWでお世話になっています!!!

コンパイルのオプションのお話から察するに、VS2013(Express for Windows Desktop?)でWin32プラットフォームの開発状態であると思いますのでその前提でお話しします。

動的リンクで成功するということですので、やはり呼び出し規則だけの問題だと思います。コンパイルオプションではなく、呼び出す関数だけ…

extern "C"
{ int __stdcall THW_read(TThLog *,...);
:};


みたいな宣言ではダメでしょうか? extern "C" は関数名のみで名前を解決するために必要で、__stdcallは hamlog50.h にWINAPIとして定義してある通り、APIのコール方法を規定してます。
.
..そういう私もDLLが呼び出せないときを想定し、動的リンクで呼び出してますが…。


> The value of ESP was not properly saved across a function call.が出てうまくいきません。
> VS2013VC++ で Hamlog50.dllを使ってHamlogの操作をしたいのです。
> アクセスに必要なHamlog50.Libも作成し関数にはextern "C" __declspec(dllexport) 及びextern "C" __declspec(dllimport)を付け
> DLL作成時も含めて__cdecl(/Gd) オプション(標準)で行っています。
> これで名前修飾もなくビルドはエラーがでず完了します。
> ところが、デバッグを行うとHamlog50.dllを呼び出す関数のところでこの警告が出てしまいます。 GetThdllVersion()等の様に引数の無いものは大丈夫なようですが(当たり前ですか)、SetDbsShare_VC(0)と単純なものでも発生します。
> 一方やむなく、 LoadLibrary(L"Hamlog50.dll")
> GetProcAddress(hDLL, "HamlogOpen")
> などからコールする方法では問題なくアクセス出来ることも確認しています。何か解決策がありそうなんですが。この辺の処うまく切り抜けておられる方アドバイスお願いいたします。
> C++側の呼び出し規約を __stdcall (/Gz) に変更すると良いとの情報も得ていますが、名前修飾の問題が解決出来ませんでした。

2014/09/30(Tue) 21:39:27  [No.578]


Re: VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 

>
> JO1SIM出島です。
> CWでお世話になっています!!!
最近ご無沙汰ですね。相変わらずCWでAJA追っかけ中です。

>
> コンパイルのオプションのお話から察するに、VS2013(Express for Windows Desktop?)でWin32プラットフォームの開発状態であると思いますのでその前提でお話しします。
>
> 動的リンクで成功するということですので、やはり呼び出し規則だけの問題だと思います。コンパイルオプションではなく、呼び出す関数だけ…
>
> extern "C"
> { int __stdcall THW_read(TThLog *,...);
> :};
>
>
> みたいな宣言ではダメでしょうか? extern "C" は関数名のみで名前
>を解決するために必要で、__stdcallは hamlog50.h にWINAPIとして>義>してある通り、APIのコール方法を規定してます。
仮のLibを作る際にも同じ指定を行い、使用する際にも指定しないと、リンクの際にエラーが出ます。__stdcall を指定すると extern "C"を付けても名前修飾が付くんですね。__cdeclではこれを付けると名前修飾が付かない。

> .
> ..そういう私もDLLが呼び出せないときを想定し、動的リンクで呼び出してますが…。
皆さん有難うございます。
やはり、__stdcall でしたか。だけどこれを指定すると、 extern "C"を指定しても、_XXXXX@ の名前修飾が付き解決出来ませんでした。depends で見るとLink状況が確認できますので。結局動的リンクで皆さん運用しているのですね。引数のない関数 Verチェックは問題なく 動くので引数の受け渡しの問題だと思っていたのですが。皆さん動的で行っておられるならこれで行きます。それにしてもなぜこちらだといけるのかな。
 動的リンクの場合 ポインターを保存しても駄目だと言う事が書いてあるので使用の際にDLL 関数のポインターを新たに取得していますが、やはり一つのサブルーチン内だけで使へと言う事ですかね。初期化で一括ポインターを取得して、あちこちで使えれば、普通のリンクと同じで使いやすいのですが。皆さんアドバイス有難うございました。

2014/10/01(Wed) 06:45:49  [No.581]


Re: VC++ Run-Time Check Failure #0 投稿者:JG1MOU浜田 

> やはり、__stdcall でしたか。だけどこれを指定すると、 extern "C"を指定しても、_XXXXX@ の名前修飾が付き解決出来ませんでした。depends で見るとLink状況が確認できますので。結局動的リンクで皆さん運用しているのですね。引数のない関数 Verチェックは問題なく 動くので引数の受け渡しの問題だと思っていたのですが。皆さん動的で行っておられるならこれで行きます。それにしてもなぜこちらだといけるのかな。

http://blogs.konuma.org/blog/2007/04/c_b43e/
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/dllusage.html

DEFファイルを使うとか、ググるといろいろあるみたいですが、
なんでご本家のVisual C++は、こんなにややこしいのでしょう!?

2014/10/01(Wed) 19:01:55  [No.582]


Re: VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 


>
> http://blogs.konuma.org/blog/2007/04/c_b43e/
> http://www.ne.jp/asahi/hishidama/home/tech/vcpp/dllusage.html
>
> DEFファイルを使うとか、ググるといろいろあるみたいですが、
> なんでご本家のVisual C++は、こんなにややこしいのでしょう!?
参考になりました。やはりDEFで解決でした。
後は、CString TCHAR char の変換が大変ですね。
多少重くなりますが、無事Hamlog50をVS2013VC++で使える様になりました。

2014/10/02(Thu) 07:30:25  [No.585]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

CSTRINGとの変換ですが、

WideCharToMultiByte/MultiByteToWideCharで変換すればよいと思いますが、検索結果をSJISのまま直接ファイルに吐き出したり、GDI等で画面に描画をするような場合ならば、邪道ですが、Wideにわざわざ変換せず、ANSIのAPIを直接呼び出してしまうような手もあると思います。

見た目の汚さや将来の互換性を考えなければですが…。

> 。
> >
> > http://blogs.konuma.org/blog/2007/04/c_b43e/
> > http://www.ne.jp/asahi/hishidama/home/tech/vcpp/dllusage.html
> >
> > DEFファイルを使うとか、ググるといろいろあるみたいですが、
> > なんでご本家のVisual C++は、こんなにややこしいのでしょう!?
> 参考になりました。やはりDEFで解決でした。
> 後は、CString TCHAR char の変換が大変ですね。
> 多少重くなりますが、無事Hamlog50をVS2013VC++で使える様になりました。

2014/10/03(Fri) 22:09:09  [No.590]


Re: VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 

> CSTRINGとの変換ですが、
>
> WideCharToMultiByte/MultiByteToWideCharで変換すればよいと思いますが、検索結果をSJISのまま直接ファイルに吐き出したり、GDI等で画面に描画をするような場合ならば、邪道ですが、Wideにわざわざ変換せず、ANSIのAPIを直接呼び出してしまうような手もあると思います。
>
一発で CString から char[] に変換方法ありますか。

TCHAR sBuf[256];

char buf[512];

int wLen;


wLen = wsprintf(sBuf, TEXT("%ls"), *b);

wLen = WideCharToMultiByte(CP_ACP, 0, sBuf, -1, buf, (sizeof buf) - 1, NULL, NULL);

return THW_seek(a, buf, c);
の様に CString を TCHAR さらにchar[]の2段階でやむなくやっています。逆も同じく
char[] を TCHAR  TCHARからCStringは = の代入で変換していますがやはり2段階でやっています。いい方法があるなら教えてください。

2014/10/04(Sat) 06:34:10  [No.591]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

銅子OM
でしまです。

CStringはLPCTSTRへのキャストが利きますので(一部冗長ですが)、

WideCharToMultiByte(CP_ACP, 0, CString(_T("なにがし")), -1,buf, sizeof(buff), NULL, NULL);

といった感じで1発変換可能ですよ。


> > CSTRINGとの変換ですが、
> >
> > WideCharToMultiByte/MultiByteToWideCharで変換すればよいと思いますが、検索結果をSJISのまま直接ファイルに吐き出したり、GDI等で画面に描画をするような場合ならば、邪道ですが、Wideにわざわざ変換せず、ANSIのAPIを直接呼び出してしまうような手もあると思います。
> >
> 一発で CString から char[] に変換方法ありますか。
>
> TCHAR sBuf[256];
>
> char buf[512];
>
> int wLen;
>
>
> wLen = wsprintf(sBuf, TEXT("%ls"), *b);
>
> wLen = WideCharToMultiByte(CP_ACP, 0, sBuf, -1, buf, (sizeof buf) - 1, NULL, NULL);
>
> return THW_seek(a, buf, c);
> の様に CString を TCHAR さらにchar[]の2段階でやむなくやっています。逆も同じく
> char[] を TCHAR  TCHARからCStringは = の代入で変換していますがやはり2段階でやっています。いい方法があるなら教えてください。

2014/10/04(Sat) 23:12:19  [No.592]


Re: VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 

>
> CStringはLPCTSTRへのキャストが利きますので(一部冗長ですが)、
>
> WideCharToMultiByte(CP_ACP, 0, CString(_T("なにがし")), -1,buf, sizeof(buff), NULL, NULL);
>
> といった感じで1発変換可能ですよ。
本当ですね。思い込みでした。うまくいきました。

2014/10/05(Sun) 07:31:36  [No.593]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

うまくいったようでなによりです。
またなにかありましたら!

> >
> > CStringはLPCTSTRへのキャストが利きますので(一部冗長ですが)、
> >
> > WideCharToMultiByte(CP_ACP, 0, CString(_T("なにがし")), -1,buf, sizeof(buff), NULL, NULL);
> >
> > といった感じで1発変換可能ですよ。
> 本当ですね。思い込みでした。うまくいきました。

2014/10/05(Sun) 11:07:24  [No.594]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

でしまです。

Netには__stdcallを指定すると extern "C"が利かなくなるというような書き込みもありますね・・・。ただ、extern "C" + __stdcallの構造はwindows.hとまったく同じなので、その中にヒントがあるかもしれません。

WinGDI.h等を見ると
extern "C"
{__declspec(dllimport) int __stdcall THW_update(...)}

と等価のような書きぶりのようです。(要は「全部つける」?)
「dllimport」の部分はDEFファイルを使っての解決することと同義かと思います。

動的リンクの場合のポインタの保管ですが、私のところではHamlog50.dllについてはLoadLibraryしてからFreeLibraryするまでの間で関数のポインタを保持しておいてもうまく動いてます。(THW2VBNET.DLLの場合では都度GetProcAddressしてますが…)



> >
> > JO1SIM出島です。
> > CWでお世話になっています!!!
> 最近ご無沙汰ですね。相変わらずCWでAJA追っかけ中です。
>
> >
> > コンパイルのオプションのお話から察するに、VS2013(Express for Windows Desktop?)でWin32プラットフォームの開発状態であると思いますのでその前提でお話しします。
> >
> > 動的リンクで成功するということですので、やはり呼び出し規則だけの問題だと思います。コンパイルオプションではなく、呼び出す関数だけ…
> >
> > extern "C"
> > { int __stdcall THW_read(TThLog *,...);
> > :};
> >
> >
> > みたいな宣言ではダメでしょうか? extern "C" は関数名のみで名前
> >を解決するために必要で、__stdcallは hamlog50.h にWINAPIとして>義>してある通り、APIのコール方法を規定してます。
> 仮のLibを作る際にも同じ指定を行い、使用する際にも指定しないと、リンクの際にエラーが出ます。__stdcall を指定すると extern "C"を付けても名前修飾が付くんですね。__cdeclではこれを付けると名前修飾が付かない。
>
> > .
> > ..そういう私もDLLが呼び出せないときを想定し、動的リンクで呼び出してますが…。
> 皆さん有難うございます。
> やはり、__stdcall でしたか。だけどこれを指定すると、 extern "C"を指定しても、_XXXXX@ の名前修飾が付き解決出来ませんでした。depends で見るとLink状況が確認できますので。結局動的リンクで皆さん運用しているのですね。引数のない関数 Verチェックは問題なく 動くので引数の受け渡しの問題だと思っていたのですが。皆さん動的で行っておられるならこれで行きます。それにしてもなぜこちらだといけるのかな。
>  動的リンクの場合 ポインターを保存しても駄目だと言う事が書いてあるので使用の際にDLL 関数のポインターを新たに取得していますが、やはり一つのサブルーチン内だけで使へと言う事ですかね。初期化で一括ポインターを取得して、あちこちで使えれば、普通のリンクと同じで使いやすいのですが。皆さんアドバイス有難うございました。

2014/10/01(Wed) 21:46:21  [No.583]


Re: VC++ Run-Time Check Failure #0 投稿者:JA9AOB 銅子 

__stdcall を指定すると extern "C"を付けても名前修飾が付くので
更にDEFで指定することで、名前修飾を取ることが出来ました。
Lib作成時にこの手法で行い、このLibでLinkを行うと無事静的にLink出来ました。もちろん、Hamlog50の関数はextern "C" や__stdcall を付けたHamlog50.hを作成しての話ですが。
やっと安心して続けられます。スタックOverなんて心配で本気になれませんでした。ではまたご指導ください。

2014/10/02(Thu) 07:17:49  [No.584]


Re: VC++ Run-Time Check Failure #0 投稿者:JO1SIM・出島 

うまくいったみたいですね。私もホッとしています。

よくよく考えると、Windowの初期からの仕様なので本来は間違えようもなく、すぐに答えが出ると思ったのですが、ネットを調べると誤った情報ばかりで、なかなかコレというまともな答えが出てこないのもにも困ったものです…。

でも、正しい答えが出ましたので、この掲示板は健全ということでしょうか!(笑)

改めて勉強になりました。

> __stdcall を指定すると extern "C"を付けても名前修飾が付くので
> 更にDEFで指定することで、名前修飾を取ることが出来ました。
> Lib作成時にこの手法で行い、このLibでLinkを行うと無事静的にLink出来ました。もちろん、Hamlog50の関数はextern "C" や__stdcall を付けたHamlog50.hを作成しての話ですが。
> やっと安心して続けられます。スタックOverなんて心配で本気になれませんでした。ではまたご指導ください。

2014/10/03(Fri) 21:57:51  [No.589]