Как получить строку из DLL на VB6
От: karp2005  
Дата: 13.12.06 00:22
Оценка:
Есть такой код на C++ (DLL):

extern "C" __declspec(dllexport) void EnumInterface(LPCTSTR p_outString) //указатель на строку
{
.....объявление переменных........
RPC_WSTR strGuid = NULL;
__try
{
..............некотроые действия.................................
if (UuidToStringW(&pIntfList->InterfaceInfo.InterfaceGuid, &strGuid) == RPC_S_OK)
{
wcscpy((LPWSTR)p_outString,(LPWSTR)strGuid);
RpcStringFreeW(&strGuid);
}
}
__finally
{
....очищаем память....
}
}

Вопрос:
1. правильно ли я возвращаю строку копируя её в область памяти, выделеной вызывающим процессом? (в случае с С — нечто типа wchar_t *test; test = new wchar_t[64]
2. Как правильно эту ДЛЛ вызвать из VB6 (чтобы вернуть в вызывающую программу строку wstring)?
Спасибо.
Re: Как получить строку из DLL на VB6
От: Vi2 Удмуртия http://www.adem.ru
Дата: 13.12.06 08:01
Оценка:
Здравствуйте, karp2005, Вы писали:

K>Есть такой код на C++ (DLL):

K>extern "C" __declspec(dllexport) void EnumInterface(LPCTSTR p_outString)  //указатель на строку
K>{
K>.....объявление переменных........
K>RPC_WSTR strGuid = NULL;
K>__try
K>{
K>..............некоторые действия.................................
K>if (UuidToStringW(&pIntfList->InterfaceInfo.InterfaceGuid, &strGuid) == RPC_S_OK)
K>{
K>wcscpy((LPWSTR)p_outString,(LPWSTR)strGuid);
K>RpcStringFreeW(&strGuid);
K>}
K>}
K>__finally
K>{
K>....очищаем память....
K>}
K>}

K>Вопрос:
K>1. правильно ли я возвращаю строку копируя её в область памяти, выделеной вызывающим процессом? (в случае с С — нечто типа wchar_t *test; test = new wchar_t[64]

Правильно, но если учесть, что LPCTSTR — это не совсем LPWSTR, то неправильно.

K>2. Как правильно эту ДЛЛ вызвать из VB6 (чтобы вернуть в вызывающую программу строку wstring)?


Никак, потому что VB умеет вызывать только stdcall функции.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Как получить строку из DLL на VB6
От: karp2005  
Дата: 13.12.06 10:28
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, karp2005, Вы писали:


K>>Есть такой код на C++ (DLL):

Vi2>
K>>extern "C" __declspec(dllexport) void EnumInterface(LPCTSTR p_outString)  //указатель на строку
K>>{
K>>.....объявление переменных........
K>>RPC_WSTR strGuid = NULL;
K>>__try
K>>{
K>>..............некоторые действия.................................
K>>if (UuidToStringW(&pIntfList->InterfaceInfo.InterfaceGuid, &strGuid) == RPC_S_OK)
K>>{
K>>wcscpy((LPWSTR)p_outString,(LPWSTR)strGuid);
K>>RpcStringFreeW(&strGuid);
K>>}
K>>}
K>>__finally
K>>{
K>>....очищаем память....
K>>}
K>>}
Vi2>

K>>Вопрос:
K>>1. правильно ли я возвращаю строку копируя её в область памяти, выделеной вызывающим процессом? (в случае с С — нечто типа wchar_t *test; test = new wchar_t[64]

Vi2>Правильно, но если учесть, что LPCTSTR — это не совсем LPWSTR, то неправильно.


K>>2. Как правильно эту ДЛЛ вызвать из VB6 (чтобы вернуть в вызывающую программу строку wstring)?


Vi2>Никак, потому что VB умеет вызывать только stdcall функции.



Поправил:
extern "C" void __declspec(dllexport) __stdcall EnumInterface(LPWSTR p_outString)
Теперь правильно?
Обращаюсь из VB k DLL так:
Declare Function EnumInterface Lib "С:\mydll.dll" (ByVal lpBuffer As String)
' Резервируется буфер, достаточный для
' размещения полного имени каталога
BufferLength& = 256
Buffer$ = Space$(BufferLength)

Call EnumInterface(Buffer$)
И тут мы слетаем......
Что я делаю снова не правильно?
Re[3]: Как получить строку из DLL на VB6
От: Vi2 Удмуртия http://www.adem.ru
Дата: 13.12.06 10:52
Оценка:
Здравствуйте, karp2005, Вы писали:

K>Поправил:

K>extern "C" void __declspec(dllexport) __stdcall EnumInterface(LPWSTR p_outString)

K>Теперь правильно?
K>Обращаюсь из VB k DLL так:
K>Declare Function  EnumInterface Lib "С:\mydll.dll"   (ByVal lpBuffer As String)

K>И тут мы слетаем......
K>Что я делаю снова не правильно?

Во-первых, EnumInterface не возвращает значение, значит, не функция, а подпрограмма.
Declare Sub EnumInterface Lib "С:\mydll.dll"   (ByVal lpBuffer As String)

Во-вторых, VB передает строки как LPSTR. Чтобы обойти преобразование строк, нужно передавать Long
Declare Sub EnumInterface "С:\mydll.dll" (ByVal s As Long)
...
  BufferLength& = 256 
  Buffer$ = Space$(BufferLength) 
Call EnumInterface(StrPtr(Buffer$))
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Как получить строку из DLL на VB6
От: Бенедикт  
Дата: 13.12.06 11:17
Оценка: +1
Разжёвано здесь.

Строки VB имеют тип BSTR.

Declare Function означает, что функция возвращает тип Variant (хотя здесь это неважно).

VBStr.h:
int WINAPI cppTEXT(LPWSTR pStr);
int WINAPI cppTEXT2(LPSTR pStr);


VBStr.cpp:
#include "stdafx.h"
#include "VBStr.h"

BOOL APIENTRY DllMain( HANDLE 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;
}

int WINAPI cppTEXT(LPWSTR pStr)
{
    wcscpy(pStr, L"У попа была собака");
    return wcslen(pStr);
}

int WINAPI cppTEXT2(LPSTR pStr)
{
    strcpy(pStr, "У пыпа была собака");
    return strlen(pStr);
}


VBStr.def
      LIBRARY   VBSTR

      EXPORTS
      cppTEXT            @1 
      cppTEXT2            @2


Form1.frm:
Option Explicit

Private Declare Function cppTEXT Lib "VBStr.DLL" (ByVal STRAddr As Long) As Long

Private Declare Function cppTEXT2 Lib "VBStr.DLL" (ByVal STR As String) As Long

Function MYTEXT() As String
 Dim MyStr As String
 MyStr = String$(255, vbNullChar)
 MYTEXT = Left$(MyStr, cppTEXT(StrPtr(MyStr)))
End Function

Function MYTEXT2() As String
 Dim MyStr As String
 MyStr = String$(255, vbNullChar)
 MYTEXT2 = Left$(MyStr, cppTEXT2(MyStr))
End Function

Private Sub Command1_Click()
 Label1.Caption = "<<" & MYTEXT() & ">>"
 Label2.Caption = "<" & MYTEXT2() & ">"
End Sub
Re[2]: Как получить строку из DLL на VB6
От: karp2005  
Дата: 13.12.06 11:48
Оценка:
Разобрался, спасибо за совет.
Последняя проблемма была на строоне ВБ.
Re[4]: Как получить строку из DLL на VB6
От: karp2005  
Дата: 13.12.06 21:30
Оценка:
Спасибо, получилось, как-то работает. Кому интересно — ещё одна статейка на тему:

http://www.microsoft.com/Rus/Msdn/Activ/MSVB/Archive/WindowsAPI/Default.mspx

Тут на примере API, возвращающих строку. Смысл тот-же, на рус.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.