Pergunta
Eu tenho uma DLL do Windows que escrevi, escrita em C/C++ (todas as funções exportadas são 'C').A DLL funciona bem para mim no VC++.Entreguei a DLL para outra empresa que faz todo o desenvolvimento em VB.Eles parecem estar tendo problemas para vincular às funções.Não uso VB há dez anos e nem o tenho instalado.Qual poderia ser o problema?
Declarei todas as minhas funções públicas da seguinte forma:
#define MYDCC_API __declspec(dllexport)
MYDCCL_API unsigned long MYDCC_GetVer( void);
.
.
.
Alguma ideia?
Finalmente voltei a isso hoje e fiz funcionar.As respostas me colocaram no caminho certo, mas achei isso muito útil:
http://www.codeproject.com/KB/DLL/XDllPt2.aspx
Além disso, tive alguns problemas ao passar strings para as funções DLL, achei isso útil:
http://www.flipcode.com/archives/Interfacing_Visual_Basic_And_C.shtml
Solução
Usando __declspec
para exportação, o nome da função será exportado mutilado, ou sejacontêm informações de tipo para ajudar o compilador C++ a resolver sobrecargas.
O VB6 não pode lidar com nomes mutilados.Como solução alternativa, você deve desmontar os nomes.A solução mais fácil é vincular o arquivo DLL usando um definição de exportação arquivo em VC++.O arquivo de definição de exportação é muito simples e contém apenas o nome da DLL e uma lista de funções exportadas:
LIBRARY mylibname
EXPORTS
myfirstfunction
secondfunction
Além disso, você deve especificar o stdcall
convenção de chamada porque essa é a única convenção de chamada que o VB6 pode manipular.Há um projeto que usa injeção de assembly para lidar com chamadas C, mas acho que você não deseja usar esse método difícil e sujeito a erros.
Outras dicas
Tente adicionar __stdcall no final
#define MYDCC_API __declspec(dllexport) __stdcall
Temos algumas dlls C++ que interagem com nossos aplicativos VB6 antigos e todas elas têm isso no final.
Uma DLL VB6 é sempre uma dll COM.Descreverei um exemplo com o mínimo de palavras possível.Suponha que você tenha um projeto ActiveX DLL em VB6 com uma classe chamada CTest que contém um método conforme mostrado abaixo
Função pública VBCONCAT (BYVAL A AS String, ByVal B como String) como String VBConcat = A & B Função final
E você definiu o nome do projeto como VBTestlib nas propriedades do projeto VB6 e compilou o projeto como f: proj vb6 attivexdll vbtestdll.dll
Você precisa registrar a dll usando o comando do Windows regsvr32 F:\proj\VB6\ActiveXDLL\VBTestDLL.dll
agora seu código C++:
#import "F:\proj\VB6\ActiveXDLL\VBTestDLL.dll" usando namespace VBTestLib;
void CDialogTestDlg::OnButton1() {
HRESULT hresult;
CLSID clsid;
_CTest *t; // a pointer to the CTest object
_bstr_t bstrA = L"hello";
_bstr_t bstrB = L" world";
_bstr_t bstrR;
::CoInitialize(NULL);
hresult=CLSIDFromProgID(OLESTR("VBTestLib.CTest"), &clsid);
hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
__uuidof(_CTest),(LPVOID*) &t);
if(hresult == S_OK)
{
bstrR = t->vbConcat(bstrA , bstrB);
AfxMessageBox((char*)bstrR);
}
}
Isso é tudo que há para começar.