• 締切済み

VCでのDLLからVBへの文字列の引渡し

===VB(Ver.6.0 SP5)側=== Public Declare Function GetStrSample Lib "Test.dll" () As String ・・・・・ Label1.Caption = GetStrSample ===VC側(Ver6.0)=== const char *StrSample="ABCDE01234";   ・・・・ _declspec(dllexport) BSTR _stdcall GetStrSample() { CString strResult; strResult = StrSample; return strResult.AllocSysString(); } 上記のようなコードで、VC側をDLLとしてVBから呼び出すと、 Label1には "A" しか表示されず、ブレークを置いてGetStrSample の戻り値を調べてみると、0x41,0x00,0x42,0x00,のように、 0x00が挟まれてしまいました。 ( ?hex(asc(mid(GetStrSample,3,1))) のようにして調べました。)  何故なのでしょうか? 文字コードの違いでしょうか? 正常にABCDE01234が渡せるようにするにはどうすればいいでしょうか? VCは初心者で、本や他人の作ったコードやMSDNを見て作成してみました。 目的は、DLLのバージョン等の情報をVB側に渡したいのです。 よろしくお願いします。

みんなの回答

回答No.1

VCは分かりませんが、 unicodeのテキストをバイナリエディタでみると 0x00が挟ませています。 それで参考にしてください。 Private Sub Form_Load() Dim buf As String buf = Chr(&H41) & Chr(&H0) & Chr(&H42) & Chr(&H0) & Chr(&H43) & Chr(&H0) Text1 = buf Text2 = StrConv(buf, vbFromUnicode) End Sub

Mihono3326
質問者

お礼

早速回答ありがとうございました。 ご回答を参考にして、 StrConv関数をかませてみたら、正常に表示されるようになりました。 Label1.Caption = StrConv(GetStrSample, vbFromUnicode) やはり、コードの問題のようですね。 対症療法的には、これで充分実用になります。 ありがとうございます。 ただ、不思議なのは、VC側のこの部分、 _declspec(dllexport) BSTR _stdcall GetStrSample() { CString strResult; strResult = StrSample; return strResult.AllocSysString(); } これは、あるところで使われている関数を殆どそのまま持ってきたのですが、 そこでは、上記のような変換関数は必要なく、正常に表示されるのです。 それは、DLLではなくてOCXなのですが、何か違うのでしょうか? (VCのカテゴリーで質問しようか迷いましたが、同種の質問がVBにたくさんありましたので、こちらにしました。) 誰かご存知の方、おりませんでしょうか?

関連するQ&A

  • VC++6.0で作成したDLLのクラスをVB6.0でインポートするには?

    VC++6.0で作成したDLLのクラスをVB6.0でインポートするにはどうしたらいいのでしょうか? 通常の関数なら__declspec(dllexport) __stdcall を書き,defファイルにEXPORT指定することで解決できたのですが,クラスごとエクスポートする場合にはVC側,VB側の記述をどのようにすれば良いのでしょうか?

  • VBからMFC-DLL呼び出し

    VC++6.0でDLLを作成してVBから呼んでいます。 VC++6.0 __declspec(dllexport) BSTR WINAPI FunA() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strA = _T("This is the テストです。.愛する</CsvData>"); return strA.AllocSysString(); } VB6.0 Private Declare Function FunA _ Lib "Communication.dll" () As String Dim strRet As String strRet = StrConv(FunA(), vbFromUnicode) これを実行すると 『This is the テストです。.愛す?</CsvData>』 がstrRetに格納されます。 『愛する』→『愛す?』になってしまうんですが、 どうしてでしょうか。

  • Cで作成したDLL関数をVBから呼ぶ(.NET)

    以前の質問に「Cで作成したDLL関数をVBから呼ぶ」(QNo.1703839)がありますが、下記のコードを見るとVB6での内容だと思います。 Dim keydata As String * 128 keydata = String$(128, Chr(0) & Chr(0)) VB.NETでVC++のDLLで変更した文字列を受けたいのですが、 どのようにすればよいのでしょうか? VB.NET2003 <DllImport("DllTest.dll")> Private Shared Function _ Test(ByVal s1 As String) As String End Function Private Sub btnTest_Click(...) ... Dim s1 As String = "abc" Dim s2 As String Dim s3 As String s2 = Test(s1) MessageBox.Show(s2) ' "1"が表示される s3 = StrConv(s2, VbStrConv.None) MessageBox.Show(s3) ' 同じく"1"が表示 end sub VC++のDLL extern "C" __declspec (dllexport) BSTR __stdcall Test(char* s1) { AfxMessageBox(s1); // "abc"が表示される OK strcpy(s1, "123"); CString s2; s2 = "123"; return s2.AllocSysString(); } また、文字列に全角を含めても大丈夫でしょうか? Unicodeの変換処理を行う必要があるのでしょうか? よろしくお願いします。

  • VB6から参照可能なDLLの作成

    VB6から参照可能なDLLの作成を参考書をみながらしましたが、上手くいかない為質問させていただきます。 開発環境VC++ 2005 C++ CTEST.dll #include <windows.h> __declspec (dllexport) int __stdcall test(int i) { i = i + 5; return i; } .defファイル LIBRARY "test" DESCRIPTION EXPORTS A 以上でDLLを作成し、VB6側で Private Declare test Lib "CTEST.dll" (ByVal i as integer) で宣言しても「エラー53 ファイルがみつかりません」と表示されます。「参照の追加」から参照しようとしても「このファイルは参照できません。」をエラーがでてしまいます。 直すべき点はどの部分なのでしょうか? ご教示ねがいます。

  • Cで作成したDLL関数をVBから呼ぶ

    以前にあった「Cで作成したDLL関数をVBから呼び 引数渡し方法」を試したのですがVB側でデータが受け取れません。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=711327 C側での値設定がわるいのでしょうか? VB側 Public Declare Function testAP Lib "C:\bin\test.dll" (ByVal lpKeyData As String) As Long --------------------------------------------------------------------------- Dim lngRc As Long Dim keydata As String * 128 keydata = String$(128, Chr(0) & Chr(0)) lngRc = testAP(keydata) VC側 __declspec(dllexport) long __stdcall testAP(char *lpdata){ →C側でlpdataに値を設定する lpdata="ABCDEF"; }

  • C#からVC++DLLの呼び出しに失敗する

    VS.NET2005のC#からVC++6.0で作成したDLLを呼び出しています。 VCのデバッガでデバッグしてみると呼び出した関数は正常に動作しているようなのですが、最後のreturnを実行しC#に戻るところでエラーが出てしまいます。 C#側では「'System.ExecutionEngineException' のハンドルされていない例外が ConsoleApplication1.exe で発生しました。」となります。 C#での宣言は、 [DllImport("test.dll")] public static extern uint TestFunc(ref byte[] moji, ref uint nagasa); です。 VC++の宣言は、 __declspec(dllexport) unsigned long __stdcall TestFunc(unsigned char* moji, unsigned long* nagasa) です。 C#へ値を返さない関数は問題ないのですが、値を返そうとすると起きるようです。不備などあればご指摘いただけないでしょうか。 ちなみにVB6からは問題なく動作できました。

  • Cで作成したDLLをVBで呼出

    Cで作成したDLLの関数をVB6.0から呼び出す事ができず、悩んでおります。 ご教授お願いします。 どの様な関数を呼び出そうとしているのかというと、以下の通りです。 <DLL Cで作成(コンパイラVC6)> void WINAPI hoge(BSTR pgname,BSTR fmt,...){ ~処理~ } /* 宣言では頭にDLLExport*/ <呼出側 VB6.0で作成> '宣言 Public Declare Function hoge Lib "hoge" _ (ByRef pgname as String , _ ByRef fmt as String , _ ParamArray args()) '呼出 call hoge("foo","baa","array1",2) この様なコードを書いております。 C側、VB側ともに固定数の引数にしてみたところ、 通ったので「ParamArray args()」の定義が違うのではないか・・・?と思っているのですが、 どの様に宣言したらよい物なのでしょうか? もしくは、そもそも全然違う箇所を間違っているのでしょうか? 宜しくお願いします。 ※ 説明の足りない箇所があれば、仰ってください。

  • VB.netでのVC++呼び出し引数の順番

    VC++で作成されたDLLをVB.NetにてそのDLLを呼び出すアプリを作成して います。以下のパターン2では問題なく動作しますが、パターン1では DLL側で見たときにchar変数に正しく値が入りません(NULL)になる。 パターン1とパターン2の違いは引数の順番です。 開発環境:VisualStudio2008 OS:WindowsXP SP2 パターン1(この場合はNG)  VC++側の宣言   extern "C" __declspec(dllexport) void func1(int i,char*s)  VB.Net側の宣言   <System.Runtime.InteropServices.DllImport("func.dll")> _   Public Sub func1(ByVal i As Long, ByVal s As String)   End Sub パターン2(この場合はOK)  VC++側の宣言   extern "C" __declspec(dllexport) void func1(char*s,int i)  VB.Net側の宣言   <System.Runtime.InteropServices.DllImport("func.dll")> _   Public Sub func1(ByVal s As String ,ByVal i As Long)   End Sub VC++側がパターン1で作成さているため、VC++側を修正をしないで 正常に動かすことは可能でしょうか? よろしくお願いします。

  • VC2005のDLLを6.0で呼び出すには

    VC 2005 Pro Editionで作ったライブラリ(ヘッダ、lib、dll)を頂きました。    頂いたDLLの形式は定義ファイル.defを使わない形式、declspec(dllexport)を使う形式の方です。  呼び出し側はVC6.0EnterPrize(SDK)を使います。 (諸事情により6.0以上にUPすることは不可能)     まず、静的リンクをし、関数を呼び出してみました。  (設定のリンクよりlibをリンクさせ、ヘッダをインクルードして)  すると以下のメッセージが出てしまいます。 リンク中... Dialog1.obj : error LNK2001: 外部シンボル ""__declspec(dllimport) void __cdecl Init(unsigned char *,unsigned char *,unsigned char *,unsigned char *)" (__imp_?Init_Card@@YAXPAE000@Z)" は未解決です Debug/CardMake.exe : fatal error LNK1120: 外部参照 1 が未解決です 。 link.exe の実行エラー    色々やってみましたが、このエラーから回避できませんでした。  ヘッダ自体に #ifdef _USRDLL #define DLL_PORT __declspec(dllexport) #else #define DLL_PORT __declspec(dllimport) #endif    の宣言があるので、別に特別なことをしなくても、大丈夫そうなのですが、何故か出来ません。  次に動的リンクを行っていました。  するとLoadLibraryでエラーになり、GetLastErrrorで14001(エラーメッセージはつかめず)が返ってきました。 (色々調べたところ定義ファイルがないと動的リンクはできないようですね)    というわけでにっちもさっちも行かなくなった状況です。  そこでご質問です。 (1)定義ファイルを使わない形式のライブラリ(暗示的に定義されているもの)はどのように呼び出させばよいでしょうか? (2)2005のライブラリを6.0から呼び出すことは可能ですか?  また呼び出す方法は?  すいませんがご回答をお願いします。

  • MFC-DLL VBからCallしStackError[No.741430の続き]

    #DLLをCOMにしたり、タイプライブラリを作成すればString型(BSTR)でも 特に問題はなくなります。 VC++で文字列を返すDLLを作ってVBで呼んでいます。 DLLの中でのスタック(Stack)サイズの問題みたいですが、 DLLは自分のスタックを持たなくてそれを使うAppのスタックを使うとしていますが、間違っていたら教えてください。そしてどうすればこのエラーを避けることができて、ただしくデータをVB側で受け取ることができるのでしょうか。 しかし返すデータが大きく(たとえば3MBの文字列)なると『実行エラー28 スタック領域が不足しています。』というエラーメッセージが出て終了されます。 VC++6.0 __declspec(dllexport) VARIANT WINAPI FunA() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); COleVariant vntA = <3MB程度の文字列> ; return vntA.Detach(); } VB6.0 Private Declare Function FunA _ Lib "Communication.dll" () As Variant Dim strRet As String strRet = FunA()

専門家に質問してみよう