初めて質問させていただきます
C++でDLLを作成し、それをExcelのVBAから呼出して使っています
数値の受渡しはうまくいっているのですが
文字列の受渡しを行う方法がわかりません
この場合の文字列の受渡し方法を教えて下さい
なお、DLLの中では、単純な数値計算を行っています
C++はVC++.Netを、Excelは2003を使っています
WinAPIのように文字列バッファを渡す方法が簡明です。
' VB
Declare Sub Test Lib "xxxx.dll" (ByVal str As String)
〜
Dim str As String
str = String(256, vbNullChar)
Test str
str = Left$(str, InStr(str, vbNullChar)-1)
' VC
void WINAPI Test( char* str )
{
strcpy( str, "てすと" );
}
文字列バッファを渡したくないのであれば、SysAllocString関数を使うことになります。
' VB
Declare Sub Test Lib "xxxx.dll" (ByRef str As String)
〜
Dim str As String
Test str
' VC
void WINAPI Test( BSTR* str )
{
SysFreeString( *str );
*str = SysAllocString( L"てすと" ); // SysAllocStringByteLenの方かも
}
ちなみに VB→DLL の一方通行であれば、単に
' VB
Declare Sub Test Lib "xxxx.dll" (ByVal str As String)
〜
Dim str As String
str = "TEST"
Test str
' VC
void WINAPI Test( const char* str )
{
MessageBox( NULL, str, "", MB_OK );
}
でOK。
> SysAllocStringByteLenの方かも
でした。
一応、全パターンのサンプルを載せます。(使わないのもある)
// VC
void WINAPI Sample01A( const char* p )
{
::MessageBoxA( NULL, p, "", MB_OK );
}
void WINAPI Sample01W( const wchar_t* p )
{
::MessageBoxW( NULL, p, L"", MB_OK );
}
void WINAPI Sample02A( char* p, int size )
{
const char s[] = "Hello World";
if ( size >= sizeof( s ) )
{
strcpy( p, s );
}
}
void WINAPI Sample02W( wchar_t* p, int size )
{
const wchar_t s[] = L"Hello World";
if ( size >= sizeof( s ) / sizeof( s[ 0 ] ) )
{
wcscpy( p, s );
}
}
void WINAPI Sample03A( BSTR* b )
{
const char s[] = "Hello World";
::SysFreeString( *b );
*b = ::SysAllocStringByteLen( s, sizeof( s ) - 1 );
}
void WINAPI Sample03W( BSTR* b )
{
const wchar_t s[] = L"Hello World";
::SysFreeString( *b );
*b = ::SysAllocString( s );
}
BSTR WINAPI Sample04A()
{
const char s[] = "Hello World";
return ::SysAllocStringByteLen( s, sizeof( s ) - 1 );
}
BSTR WINAPI Sample04W()
{
const wchar_t s[] = L"Hello World";
return ::SysAllocString( s );
}
' VBA
Private Declare Sub Sample01A Lib "VBDLL.dll" (ByVal s As String)
Private Declare Sub Sample01W Lib "VBDLL.dll" (ByVal s As Long)
Private Declare Sub Sample02A Lib "VBDLL.dll" (ByVal s As String, ByVal l As Long)
Private Declare Sub Sample02W Lib "VBDLL.dll" (ByVal s As Long, ByVal l As Long)
Private Declare Sub Sample03A Lib "VBDLL.dll" (ByRef s As String)
Private Declare Function Sample04A Lib "VBDLL.dll" () As String
Sub Test1()
Dim s As String
s = "Hello World"
Sample01A s
Sample01W StrPtr(s)
End Sub
Sub Test2()
Dim s As String
s = String(256, vbNullChar)
Sample02A s, 256
s = Left$(s, InStr(s, vbNullChar) - 1)
MsgBox s
s = String(256, vbNullChar)
Sample02W StrPtr(s), 256
s = Left$(s, InStr(s, vbNullChar) - 1)
MsgBox s
End Sub
Sub Test3()
Dim s As String
Sample03A s
MsgBox s
End Sub
Sub Test4()
Dim s As String
s = Sample04A()
MsgBox s
End Sub
VARIANTを使う方法もあります・
Blueさん、ありがとうございます
ご教示いただいた方法でうまくいきました
ツイート | ![]() |