tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルVB6.0のExeとVC++6.0のDLLの文字列
記事No12320
投稿日: 2008/05/20(Tue) 14:56
投稿者VB
☆VB6.0
・標準モジュール
Public Declare Function test Lib "test.dll" (ByRef PINFO() As DLL) As Long
Public Type DLL
    flg As String * 1
End Type
・フォーム
Dim PINFO(0) As DLL
Dim rtn As Long
PINFO(0).sflg = "X"
rtn = clhsmain(PINFO)
Text1.Text = rtn
-------------------------------------------------------------------------------
☆VC++6.0
_declspec(dllexport) WINAPI test(const DLL* PINFO[1])
{
    int   fret;
    if  ((PINFO[0]->flg  != "X") && (PINFO[0]->flg  != "Y"))   <=
    {
        fret = 0 - 11;
        return(fret);
    }
    
    return 0;
}

struct DLL{
    char    flg[1];
};

--------------------------------------------------------------------------------
はじめまして。
早速質問なのですが。
上記のプログラムを見てもらうとなんとなくやりたい事がわかってもらえるかと思いますが、
VC++で作ったDLLをVBで使おうとしているわけなんですが。
VBでflgという変数に"X"か"Y"のどちらか入力し、
その判別をVC++のDLLで文字を判別しReturnを返したいのですが。
『<=』この矢印の部分でその判別の式としてIf文が書かれているところで
その入っている変数を確認すると必ず「1 "£"」と言う値が入ってしまっていて
うまく受け渡しが出来ていません。
どのようにすれば、VC++のDLLでVBの文字列を判別することが出来るでしょうか?
アドバイス宜しくお願いいたします。
初心者なので説明不足も多々あると思います。何か他に必要な情報があれば言って下さい。
では、お待ちしております。

[ツリー表示へ]
タイトルRe: VB6.0のExeとVC++6.0のDLLの文字列
記事No12321
投稿日: 2008/05/20(Tue) 15:34
投稿者魔界の仮面弁士
> Public Declare Function test Lib "test.dll" (ByRef PINFO() As DLL) As Long
[ByRef x() As ユーザー定義型] だと、SAFEARRAY の意味になってしまいます。

今回の場合は、[ByRef x As ユーザー定義型] にして PInfo(0) を渡すか、
あるいは、[ByVal x As Long] にして VarPtr(PInfo(0)) を渡してみてください。


> Public Type DLL
> flg As String * 1
> End Type
---
> PINFO(0).sflg = "X"
ん? メンバ名が異なっているような。


> その入っている変数を確認すると必ず「1 "£"」と言う値が入ってしまっていて
最初の 1 は、SAFEARRAY 中の次元数を表す情報(unsigned short cDims)かな…。

[ツリー表示へ]
タイトルRe^2: VB6.0のExeとVC++6.0のDLLの文字列
記事No12322
投稿日: 2008/05/20(Tue) 16:56
投稿者VB
> 今回の場合は、[ByRef x As ユーザー定義型] にして PInfo(0) を渡すか、
> あるいは、[ByVal x As Long] にして VarPtr(PInfo(0)) を渡してみてください。
前者の『[ByRef x As ユーザー定義型] にして PInfo(0) を渡す』
で実行してみたところ。
VB
・標準モジュール
Public Declare Function test Lib "test.dll" (ByRef PINFO As DLL) As Long
・フォーム
Dim PINFO(0) As DLL
PINFO(0).flg = "X"
と書き直しました。
ですが、VC++では『式を評価出来ません』という返答が・・・。

後者の『[ByVal x As Long] にして VarPtr(PInfo(0)) を渡す』
で実行してみたところ

VB
・標準モジュール
Public Declare Function test Lib "test.dll" (ByRef PINFO As DLL) As Long
・フォーム
Dim PINFO(0) As DLL
PINFO(0).flg = "X"
rtn = VarPtr(PINFO(0))
Text1.Text = rtn
と書き直しましたが、7桁の数値が返ってきてしまいました。
何がいけなかったのでしょう?(^^;

> > flg As String * 1
> > PINFO(0).sflg = "X"
> ん? メンバ名が異なっているような。
打ち間違えました(^^;
すみません。

> 最初の 1 は、SAFEARRAY 中の次元数を表す情報(unsigned short cDims)かな…。
おそらくそれです。。

[ツリー表示へ]
タイトルRe^3: VB6.0のExeとVC++6.0のDLLの文字列
記事No12323
投稿日: 2008/05/20(Tue) 17:45
投稿者魔界の仮面弁士
# DLL 側の仕様は横においといて、VB 側の話だけに反応。

> 後者の『[ByVal x As Long] にして VarPtr(PInfo(0)) を渡す』
> で実行してみたところ
> Public Declare Function test Lib "test.dll" (ByRef PINFO As DLL) As Long
「ByVal Long」ではなく、「ByRef ユーザー定義型」になっていますね。

> rtn = VarPtr(PINFO(0))
> Text1.Text = rtn
何のために、ポインタ(変数のアドレス)を表示しているのでしょうか?

> と書き直しましたが、7桁の数値が返ってきてしまいました。
そもそも 7 桁とは限りません。たまたま 7 桁であっただけでしょう。

[ツリー表示へ]
タイトルRe^4: VB6.0のExeとVC++6.0のDLLの文字列
記事No12327
投稿日: 2008/05/21(Wed) 10:24
投稿者VB
状況は少し変わりまして。。
----------VB----------------------------------------------------------------
☆標準モジュール
Public Type DLL
  flg1 As String
    flg2 As String
End Type
Public Declare Function test Lib "test.dll" (PINFO As DLL) As Long
☆フォーム
Dim PINFO(0) As DLL
Dim rtn As Long
    PINFO(0).flg1 = "X"
    PINFO(0).flg2 = "Y"
rtn = test(PINFO(0))
Text1.Text = rtn
--------------------------------------------------------------------------------
----------------VC++------------------------------------------------------------
typedef struct DLL{
    char    flg1;
    char    flg2;
};

_declspec(dllexport) int WINAPI test(const DLL* PINFO[1])
{
    int   fret;

    if  ((PINFO[0]->flg1 != 'X' ) && (PINFO[0]->flg1 != 'Y'))
    {
        fret = 0 - 12;
        return(fret);
    }

    if  ((PINFO[0]->flg2 != 'X') && (PINFO[0]->flg2 != 'Y'))
    {
        fret = 0 - 13;
        return(fret);
    }

    return 0;
}

上記のようなプログラムを作ったのですが。
VC++でデバックを行うと
PINFO[0]->flg1 = "X"
PINFO[0]->flg2 = ""
PINFO[1]->flg1 = "Y"
PINFO[1]->flg2 = ""
の値が入ってしまいます。
Q1.
VC++でPINFO[1]と書いているのになぜ2つ目のテーブルが出来てしまうのか。
分かりましたら宜しくお願いいたします。

Q2.
試しにVBの構造体の宣言で
Public Type DLL
  flg1 As String * 1
    flg2 As String * 1
End Type
としてみたところひとつのテーブルで値が代入されたのですが
文字化けしてしまいました。
これを防ぐ方法もありましたら宜しくお願いいたします。

魔界の仮面弁士さまいつもありがとうございます。
少しずつですが、進行しています。。

[ツリー表示へ]
タイトルRe^5: VB6.0のExeとVC++6.0のDLLの文字列
記事No12328
投稿日: 2008/05/21(Wed) 14:42
投稿者VB
上記の件は自己解決致しました。
ありがとうございました。。
お騒がせ致しました。。

そして、新たな問題が!(^^;
----------VB----------------------------------------------------------------
☆標準モジュール
Public Type DLL
  flg1 As String
    flg2 As String
End Type
Public Declare Function test Lib "test.dll" (PINFO As DLL) As Long
☆フォーム
Dim PINFO(0) As DLL
Dim rtn As Long
    PINFO(0).flg1 = "X"
    PINFO(0).flg2 = "Y"
rtn = test(PINFO(0))
Text1.Text = rtn
--------------------------------------------------------------------------------
----------------VC++------------------------------------------------------------
typedef struct DLL{
    char    *flg1;
    char    *flg2;
};

_declspec(dllexport) int WINAPI test(const DLL* PINFO)
{
    if ((*(PINFO->flg1) != 'X') && (*(PINFO->flg1) != 'Y'))
    {
        return 1;
    }

    if ((*(PINFO->flg2) != 'X') && (*(PINFO->flg2) != 'Y'))
    {
        return 2;
    }
    return 0;
}

上記のようにすることによって
PINFO->flg1 = "X"
PINFO->flg2 = "Y"
と入るようになったのですが。
そもそもこの構造体で行いたかったことが
VBで
Dim PINFO(1) As DLL
Dim rtn As Long
    PINFO(0).flg1 = "X"
    PINFO(0).flg2 = "Y"
    PINFO(1).flg1 = "X"
    PINFO(1).flg2 = "Y"
↑このような複数のテーブルを渡したいのですが、
上記のように定義したときまた値の取得仕方がいけないのか
構造体に変な値が入ってきてしまいます。
例となるプログラムがありましたら宜しくお願いいたします。

[ツリー表示へ]