2009-03-03 17 views
17

Come posso passare un char * dalla DLL C a VBCome convertire char * in BSTR?

Ecco il codice di esempio:

void Cfunc(char *buffer,int len) 
{ 
    BSTR buf_bstr = SysAllocString((BSTR)buffer); 
    VBptr.VBfunc(buf_bstr,len); 
} 

Questa funzione non funziona, In effettivi alcuni altri valori vengono inviati al VB, piuttosto che l'attuale valore.

Qualcuno potrebbe suggerire una soluzione?

+0

Puoi dare un esempio di una stringa originale rispetto al valore errato che viene inviato? –

+0

Il tuo problema (originale) sembra essere la larghezza del carattere. Un BSTR è sempre caratteri ampi (COM è tutto Unicode). Un cast non allargherà automaticamente i caratteri, ma interpreterà i byte come wchar_t *. – Richard

+0

Questo pseudocodice presenta una perdita di memoria. Si chiama SysAllocString(), ma non rilasciare la stringa dopo che non ne hai più bisogno. – sharptooth

risposta

2

Non ho alcuna obiezione a ajryan di risposta, ma qui è un'alternativa ...

SysAllocString è definito a prendere una parametro di tipo OLECHAR *. Gli stai dando un char *. Queste non sono la stessa cosa Ci sono alcune circostanze in cui potrebbero essere la stessa cosa, ma non puoi dipendere da esso. Quindi prima di tutto devi convertire il tuo char * in un OLECHAR *. C'è una macro chiamata A2OLE che può farlo per te, e in quei casi in cui char * e OLECHAR * sono la stessa cosa, la macro non compila a nulla (penso).

Vedere this page per i dettagli di A2OLE e dei suoi amici.

Oh, e trasmettere il tuo char * a un BSTR in realtà non lo cambia affatto, non è né un BSTR né un OLECHAR *.

+0

Btw, il casting di un WCHAR * in BSTR è una cattiva idea anche se la stringa non è stata allocata con una delle funzioni di famiglia SysAllocString(). Ciò potrebbe causare un arresto anomalo se la chiamata che si passa a tale pseudo-BSTR chiama SysStringLen() su di esso. – sharptooth

21

Chiama MultiByteToWideChar(), quindi SysAllocString() o SysAllocStringLen().

Non dimenticare di chiamare SysFreeString() quando non è più necessario il BSTR.

In dettaglio (SysAllocStringLen() variante - è più breve e più veloce):

  1. chiamata MultiByteToWideChar() e passare 0 come parametri quinto e sesto. Restituirà il numero di caratteri nell'equivalente Unicode della stringa ANSI. Ricorda, la stringa ANSI può contenere qualsiasi carattere, non solo ASCII, quindi qualsiasi tentativo di calcolare manualmente il numero di caratteri Unicode data la lunghezza della stringa ANSI può funzionare in alcuni casi e non funzionare in altri.

  2. Assegnare un buffer per BSTR con SysAllocStringLen(). Passa 0 come primo parametro e il numero di caratteri Unicode come secondo parametro. Ora hai un BSTR correttamente assegnato ma non inizializzato. Ha già posto per lo zero finale e questo zero finale è posizionato correttamente.

  3. Chiama MultiByteToWideChar() la seconda volta e questa volta passa il BSTR assegnato lì. La funzione convertirà la stringa in Unicode e copierà il risultato nel BSTR. Ora disponi di un BSTR appositamente assegnato contenente l'equivalente Unicode della tua stringa ANSI.

  4. Passare il BSTR in VB. Godere.

  5. Chiama SysFreeString() per deallocare il BSTR.

+0

Ancora il mio codice non funziona, ho modificato in questo modo. void Cfunc (char * buffer, int len) { BSTR buf_bstr; ULONG cCharacters; if (0 == MultiByteToWideChar (0, 0, buffer, caratteriC, buf_bstr, cCharacters)); VBptr.VBfunc (buf_bstr, len); } VB Exe si è arrestato in modo anomalo. –

+0

Ciao Sharptooth .. sono nuovo a questo COM :( –

+1

Ho modificato la risposta per includere un passo-passo come fare. – sharptooth

10

Questo è il codice che ho scritto usando sharptooths risposta

int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0); 
    BSTR bstr = SysAllocStringLen(0, wslen); 
    MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen); 
    // Use bstr here 
    SysFreeString(bstr); 

noti che usare -1 per la lunghezza di una stringa costituisce il terminatore nullo essendo inclusa nel risultato

1

invece di char * array, prova _tchar * array. Perché Sysallocstring accetta solo i caratteri Unicode in un'applicazione a 32 bit.

Problemi correlati