Avatar billede nanosoft00 Nybegynder
03. august 2003 - 11:48 Der er 14 kommentarer og
1 løsning

Return en streng fra en C++ DLL til Visual Basic

Jeg har lavet et C++ projekt i MSVC++
og jeg kan få DLL'en til at returnere en int, men når det skal være en streng så hopper kæden af, enten får jeg Bad DLL Calling Convention eller også crasher VB.

### VB code ###
Private Declare Function strHelloWorld3 Lib "TheDLL.dll" Alias "HelloWorld3" () As String

Dim strReturn2 As String
strReturn2 = strHelloWorld3()
MsgBox strReturn2


### C++ ###
__declspec(dllexport) string stringtest2( void)
{
return "jammen lige her!!!";
}

### .def ###
HelloWorld3 =?stringtest2@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
Avatar billede soreno Praktikant
03. august 2003 - 13:50 #1
Måske det er smartere at bruge et chararray og call-by-reference..

F.eks.
__declspec(dllexport) void stringtest2( char *buffer, int bufferSize)
{
  //brug af metoder til at fylde info på buffer
}

Sådan gør win32api.

Jeg kender intet til VB så jeg ved ikke hvordan det skal kaldes. Men hvis du ved hvordan du f.eks. kalder GetWindowsDirectory(LPTSTR lpBuffer, UINT uSize) så er det samme princip du skal benytte.
Avatar billede arne_v Ekspert
03. august 2003 - 15:47 #2
En STL string duer slet ikke.

En C string (char array nul termineret) duer heller ikke.

Prøv med:

#include "windows.h"
#include "wtypes.h"
#include "oleauto.h"

__declspec(dllexport) BSTR stringtest2(void)
{
  char s[] = "jammen lige her!!!";
  return SysAllocStringByteLen(s,strlen(s));
}
Avatar billede arne_v Ekspert
03. august 2003 - 15:48 #3
Og spørg mig ikke om hvorfor, men når C++ skal returnere en
stringe til VB, så skal man bruge SysAllocStringByteLen.
Avatar billede nanosoft00 Nybegynder
03. august 2003 - 21:19 #4
jeg får disse compiler fejl:

TheDLL.cpp(69) : error C2146: syntax error : missing ';' before identifier 'stringtest2'
TheDLL.cpp(69) : error C2501: 'BSTR' : missing storage-class or type specifiers

jeg tror det er fordi der mangler en include, jeg har sat de tre ind du har skrevet
Avatar billede arne_v Ekspert
03. august 2003 - 21:25 #5
Mystisk jeg har kun:

#include "windows.h"
#include "wtypes.h"
#include "oleauto.h"
#include "stdafx.h"

(plus nogle ikke MSVC++ filer)
Avatar billede arne_v Ekspert
03. august 2003 - 21:28 #6
I VC++ 6  indeholde wtypes.h:

typedef /* [wire_marshal] */ OLECHAR __RPC_FAR *BSTR;
Avatar billede nanosoft00 Nybegynder
03. august 2003 - 21:39 #7
mystisk...

dette kompiler fint i en normal console exe
***************************
#include "windows.h"
#include "wtypes.h"
#include "oleauto.h"

BSTR mystring;

void main()
{

mystring = SysAllocString(L"hello world");
}

jeg bøvler lidt videre
Avatar billede nanosoft00 Nybegynder
03. august 2003 - 22:48 #8
nu virker det sku... jeg skulle bare lige flytte lidt rundt på mine include kald, og slette en enkelt der blev included dobbelt.

jeg har også fundet ud af hvorfor man skal bruge SysAllocString() se evt. her
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap7_2xgz.asp

det har noget at gøre med ANSI strings og UNICODE strings, en CHAR er ANSI hvor der bruges en byte per bogstav, hvor UNICODE bruger to bytes, bla. fordi der så er plads til alle de underlige tegn (Læs: Japanske/kinesiske)

Men arne du har fortjent dine point, nu kunne du vel ikke også lige fortælle mig hvordan jeg sender en string til DLL'en fra VB
Avatar billede arne_v Ekspert
03. august 2003 - 22:54 #9
Som input i argument-listen bruger du bare:
  const char *foobar

Det har altid virket for mig.
Avatar billede arne_v Ekspert
03. august 2003 - 22:55 #10
Jeg tror der er lidt mere i SysAllocString end bare karakter-sæt.

Første sætning i det link du angav er:
  To handle strings that are allocated by one component and freed by another
Avatar billede nanosoft00 Nybegynder
03. august 2003 - 23:19 #11
okey... jeg er ikke så hård til dette i nu :)
startede på C++ for 3 dage siden
det virker ikke helt...

THEDLL_API int stringtest2(const char *foobar)
{
  //char s[] = "jammen lige her!!!";
// return SysAllocStringByteLen(buffer,bufferSize);
return 534;
}

Private Declare Function stringtest2 Lib "TheDLL.dll" (ByRef foobar As String) As Integer

så fortæller den mig: "Bad DLL calling convention" i VB
Avatar billede arne_v Ekspert
03. august 2003 - 23:33 #12
Prøv med:

Private Declare Function stringtest2 Lib "TheDLL.dll" (ByVal foobar As String) As Integer

eller:

THEDLL_API int WINAPI stringtest2(const char *foobar)

Private Declare Function stringtest2 Lib "TheDLL.dll" Alias "_stringtest2@4" (ByVal foobar As String) As Integer
Avatar billede nanosoft00 Nybegynder
03. august 2003 - 23:54 #13
glemte lige at sige..
THEDLL_API er en macro der bliver til __declspec(dllexport)

hvad betyder "WINAPI" ?
for det ser ud til at virke :)
Avatar billede nanosoft00 Nybegynder
04. august 2003 - 00:30 #14
dette virker:

THEDLL_API BSTR WINAPI stringtest4(const char *foobar)
{
return SysAllocStringByteLen(foobar,strlen(foobar));
}

Private Declare Function stringtest4 Lib "TheDLL.dll" (ByVal foobar As String) As String

jeg bruger så også en .def fil med dette i:
stringtest4 = ?stringtest4@@YGPAGPBD@Z
Avatar billede arne_v Ekspert
04. august 2003 - 07:05 #15
C/C++ på Win32 har 2 calling conventions C og Win32.

WINAPI fortæller compileren til at den skal bruge Win32 calling
convention.

Du kan muligvis erstatte din .def med en alias i VB. Og navnet kunne
nok pyntes ved at bruge extern "C".

But who cares when it works.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester