Страница 1 из 1

Подключение dll (C++) к проекту VB 6.0

Добавлено: 04 дек 2013, 09:12
Kverter
Здравствуйте! Проблемма в подключении ДЛЛ к VB 6.
есть библиотека на C++

Код: Выделить всё

//ConsoleApplication2.cpp: определяет точку входа для консольного приложения.
//
//#define _UNICODE
#pragma comment( lib, "Activeds.lib" )
#pragma comment( lib, "Adsiid.lib" )
//#pragma comment( lib , "adsldp.dll" )
//#include <activeds.h>
#include <Iads.h>
#include <Adshlp.h>
#include <winldap.h>
#include <iostream>
#include <atlbase.h>
 #include <windows.h>
   #include <lm.h>
   #include <stdio.h>
#include <Lmcons.h>
#include <string>
#include <atlconv.h>
#include <string.h>
using namespace std;
 
extern "C" __declspec(dllexport) string sAMAccountName ()
{
    HRESULT hr;
    IADsADSystemInfo *pADsys;
BSTR bstr;
CoInitialize(NULL);
 hr = CoCreateInstance(CLSID_ADSystemInfo,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IADsADSystemInfo,
                             (void**)&pADsys);
 hr = pADsys->get_UserName(&bstr);
    IADs *pUsr=NULL;

 
USES_CONVERSION;
string strDesc = static_cast<CHAR*>(CW2A(bstr));
 
 string LDAP="LDAP://";
 string path = LDAP + strDesc;  
 wstring wstr( path.begin(), path.end() );
// const char *path1 = path.c_str();
 
LPCTSTR path2 = W2CT( wstr.c_str( ) );
 //LPCWSTR path2 = (LPCWSTR)wstr;
hr = ADsGetObject( path2, IID_IADs,(void**)&pUsr);
 
VARIANT var;
VariantInit(&var);
hr = pUsr->Get(CComBSTR("sAMAccountName"), &var );
/*if ( SUCCEEDED(hr) )
{
    printf("sAMAccountName: %S\n", V_BSTR(&var) );
    VariantClear(&var);
} */
//USES_CONVERSION;
 
string s2(W2A(var.bstrVal));
return s2;
}
 
 
extern "C" __declspec(dllexport) VARIANT userPrincipalName ()
{
    HRESULT hr;
    IADsADSystemInfo *pADsys;
BSTR bstr;
CoInitialize(NULL);
 hr = CoCreateInstance(CLSID_ADSystemInfo,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IADsADSystemInfo,
                             (void**)&pADsys);
 hr = pADsys->get_UserName(&bstr);
    IADs *pUsr=NULL;
 
USES_CONVERSION;
string strDesc = static_cast<CHAR*>(CW2A(bstr));
 
 string LDAP="LDAP://";
 string path = LDAP + strDesc;  
 wstring wstr( path.begin(), path.end() );
// const char *path1 = path.c_str();
 
LPCTSTR path2 = W2CT( wstr.c_str( ) );
 //LPCWSTR path2 = (LPCWSTR)wstr;
hr = ADsGetObject( path2, IID_IADs,(void**)&pUsr);
 
VARIANT userPrincipalName;
VariantInit(&userPrincipalName);
hr = pUsr->Get(CComBSTR("userPrincipalName"), &userPrincipalName );
/*if ( SUCCEEDED(hr) )
{
    printf("userPrincipalName: %S\n", V_BSTR(&userPrincipalName) );
    VariantClear(&userPrincipalName);
} */
return userPrincipalName;
}
extern "C" __declspec(dllexport) VARIANT Group ()
{
    HRESULT hr;
    IADsADSystemInfo *pADsys;
BSTR bstr;
CoInitialize(NULL);
 hr = CoCreateInstance(CLSID_ADSystemInfo,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IADsADSystemInfo,
                             (void**)&pADsys);
 hr = pADsys->get_UserName(&bstr);
    IADs *pUsr=NULL;
 
USES_CONVERSION;
string strDesc = static_cast<CHAR*>(CW2A(bstr));
 
 string LDAP="LDAP://";
 string path = LDAP + strDesc;  
 wstring wstr( path.begin(), path.end() );
// const char *path1 = path.c_str();
 
LPCTSTR path2 = W2CT( wstr.c_str( ) );
 //LPCWSTR path2 = (LPCWSTR)wstr;
hr = ADsGetObject( path2, IID_IADs,(void**)&pUsr);
 
VARIANT var;
VariantInit(&var);
hr = pUsr->Get(CComBSTR("memberOf"), &var );
return var;
}
extern "C" __declspec(dllexport) void out(VARIANT  var)
{
    HRESULT hr;
    LONG lstart, lend;
    SAFEARRAY *sa = V_ARRAY( &var );
    VARIANT varItem;
 
    // Get the lower and upper bound.
    hr = SafeArrayGetLBound( sa, 1, &lstart );
    hr = SafeArrayGetUBound( sa, 1, &lend );
 
    // Iterate and print the content.
    VariantInit(&varItem);
    printf("Getting service dependencies using IADs :\n");
    for ( long idx=lstart; idx <= lend; idx++ )
    {
        hr = SafeArrayGetElement( sa, &idx, &varItem );
        printf("%S ", V_BSTR(&varItem));
        VariantClear(&varItem);
    }
    printf("\n");
 
    VariantClear(&var);
}

и есть код на vb 6.0

Код: Выделить всё

Private Declare Function sAMAccountName Lib "C:\Users\1\Documents\Visual Studio 2012\Projects\ConsoleApplication18\Debug\ConsoleApplication18.dll" () As Integer
 
Private Sub Command1_Click()
Dim s As String
s = sAMAccountName
End Sub
при запуске просто зависает и все,помогите пожалуйста.
Проблема по ходу в самой библиотеке...

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 04 дек 2013, 10:54
Kverter
В общем понял я в чем проблема. Проблема в типах данных VB нужно чтоб функция из DLL возвращала тип данных hlstr, но в c++ нет такого типа, нашел некий vbapi.h где описан тип,но проблема в том что он не компилица
Ошибка 9 error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию c:\vbapi.h 837
Ошибка 14 error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию c:\vbapi.h 838
Ошибка 18 error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию c:\vbapi.h 839
Ошибка 5 error C2371: VARIANT: переопределение; различные базовые типы c:\vbapi.h 84
Ошибка 3 error C2371: HSZ: переопределение; различные базовые типы c:\vbapi.h 49
Ошибка 1 error C2371: FSHORT: переопределение; различные базовые типы c:\vbapi.h 37
Ошибка 6 error C2371: DRAGINFO: переопределение; различные базовые типы c:\vbapi.h 383
Ошибка 4 error C2371: CURRENCY: переопределение; различные базовые типы c:\vbapi.h 65
Ошибка 2 error C2371: CHAR: переопределение; различные базовые типы c:\vbapi.h 38
Ошибка 12 error C2182: _export: недопустимое использование типа "void" c:\vbapi.h 838
Ошибка 10 error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "VBTERMCC" c:\vbapi.h 838
Ошибка 7 error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "VBINITCC" c:\vbapi.h 837
Ошибка 15 error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "VBGetModelInfo" c:\vbapi.h 839
Ошибка 13 error C2086: BOOL _export: переопределение c:\vbapi.h 838
Ошибка 17 error C2040: _export: "LPMODELINFO" отличается по уровням косвенного обращения от "BOOL" c:\vbapi.h 839
вот такие ошибки, кто посоветует что делать?

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 04 дек 2013, 14:53
Romeo
Никогда и ни за что VB не поймёт STL-ный тип std::string. Возвращение из функции сложного типа, завязанного на внутренние особенности языка/библиотеки автоматически лишает эту функцию универсальности и сужает её использование рамками языка/библиотеки.

Раз у тебя библиотека внутри использует COM, то почему бы тебе не сделать собственный COM объект, а из VB просто создать его и вызвать его метод? VB отлично работает с COM.

Если не хочешь разбираться с тем, как сделать свой COM объект, то возврати из функции хотя бы BSTR. VB, вроде как, умеет работать с ним.

И ещё замечение не совсем по теме. Используй Release, когда указатели на COM объекты тебе уже не нужны. Я об этом ещё в прошлой твоей теме писал. Сейчас у тебя эта память просто ликает. Это не профессионально.

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 05 дек 2013, 10:34
Kverter
В общем,строка возвращается в проект на VB, но коряво...для ее обработки приходится использовать след.код на VB

Код: Выделить всё

NewStr3 = sAMAccountName()
For i = 1 To k Step 1
If Mid(NewStr3, i, 1) <> vbNullChar Then
Text3.Text = Text3 + Mid(NewStr3, i, 1)
End If
Next i
т.е через символ встречается vbNullChar как это исправить????я думаю проблема может быть в кодировке...
вот функция sAMAccountName() на с++

Код: Выделить всё

extern "C" __declspec(dllexport) BSTR CCONV sAMAccountName ()
{
	HRESULT hr;
	IADsADSystemInfo *pADsys;
BSTR bstr;
CoInitialize(NULL);
 hr = CoCreateInstance(CLSID_ADSystemInfo,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IADsADSystemInfo,
                             (void**)&pADsys);
 hr = pADsys->get_UserName(&bstr);
	IADs *pUsr=NULL;
USES_CONVERSION;
string strDesc = static_cast<CHAR*>(CW2A(bstr));

 string LDAP="LDAP://";
 string path = LDAP + strDesc;  
 wstring wstr( path.begin(), path.end() );
// const char *path1 = path.c_str();

LPCTSTR path2 = W2CT( wstr.c_str( ) );
 //LPCWSTR path2 = (LPCWSTR)wstr;
hr = ADsGetObject( path2, IID_IADs,(void**)&pUsr);

VARIANT var;
VariantInit(&var);
hr = pUsr->Get(CComBSTR("sAMAccountName"), &var );

return var.bstrVal;
}

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 05 дек 2013, 19:53
Romeo
BSTR в дефайнах студии - это широкая строка, так что ничего удивительного, что там идёт после каждого символа ноль. Я ожидал, что VB-сику можно будет об этом сказать, указав тип возвращаемого значения при декларации функции. Поиграйся с декларацией, возможно получится.

Если не поможет, то сделай возвращаемое значение char*. Тогда придётся сделать статический буфер символов внутри функции, конвернтуть из BSTR в него, и возвратить указатель.

P.S. Да удали ж ты память. Перед выходом из функции сделай:

Код: Выделить всё

pUsr->Release();
VariantClear(var);

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 05 дек 2013, 21:12
Kverter
Уже решил этот вопрос.....но столкнулся с другой проблемой....при переносе скомпиленого экзешника на VB в другую(чистую) систему, он ругается что не может найти мою написанную dll, хотя путь правильный и она там есть...в чем трабла?

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 06 дек 2013, 14:53
Romeo
Целиком пусть весь есть? "C:\Users\1\Documents\Visual Studio 2012\Projects\ConsoleApplication18\Debug\ConsoleApplication18.dll"

Вообще хардкодить путь в программе не принято. Убери путь, и оставь только имея dll. Тогда dll будет браться из текущей папки. То есть для запуска нужно будет exe, скомпилированный на VB и dll, скомпилированную в студии, положить в одну папку и всё будет работать, куда бы ты эту папку потом не перенёс.

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 06 дек 2013, 15:27
Kverter
Оно ни так ни так не работает, я думаю может у меня ДЛЛ имеет зависимости, только вот какие не могу понять....

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 06 дек 2013, 15:31
Romeo
В студию входи программа DependencyWalker. Её так же можно стащить в интеренете, как отдельную утилитку. Она позволяет посмотреть все депенденсы исполняемых файлов на Windows. Очень рекомендую. Скорее всего на чистом компютрере не установлены стандартные dll студии, которые линкует наша dll.

Re: Подключение dll (C++) к проекту VB 6.0

Добавлено: 06 дек 2013, 15:47
Kverter
К сожалению сейчас не могу проверить, но я так уже смотрел, там тянется 5 шт ДЛЛ , но я посмотрел они все на месте в Windows\system32, больше вроде ни каких либ не показало