2017-03-17 48 views
1

我想從VBA中獲取DLL中的整數值,如下面的代碼。如何從VBA中的DLL中獲取整數值?

double _stdcall pll_dll(double* datain0, double* datain1, double* dataout0, double* dataout1, BSTR * str, int* str_len) 
{ 
char buff[128] = { 0 }; 
char * str0; 
char str1[128] = { 0 }; 

int len; 


    *dataout0 = *datain0 + 20; 
    *dataout1 = *datain1 + 30; 
    len = 30; 
    *str_len = 30; 

    str0 = " Nice "; 
    sprintf(buff, "Hi %s \n", str0); 
    strcpy(str1, buff); 

    char* p = str1; 
    SysReAllocString(str, (OLECHAR*)p); 

    return 0; 
} 

VB

Private Declare PtrSafe Function pll_dll Lib "F:\work\pll_dll\x64\Debug\pll_dll.dll" _ 
(ByRef x_in As Double, ByRef y_in As Double, ByRef x_out As Double, ByRef y_out As Double, ByRef s As String, ByRef str_len As Integer) As Double 

Dim s_len As Integer 
Call pll_dll(3, 4, d1, d2, s, s_len) 

但我不明白,當我跑上面的代碼,s_len總是「0'at的VBA。 但其他參數double * datain0,double * datain1,double * dataout0,double * dataout1,BSTR * str都工作正常。當我運行「double _stdcall pll_dll(double * datain0,double * datain1,double * dataout0,double * dataout1,int * str_len」)時,我擺脫了「BSTR * str」參數 )「那麼我可以得到str_len以及

你能讓我知道我應該檢查什麼嗎? 如何獲得s_len值?

回答

3

您錯用了SysReAllocString()

您正在給它一個8位ANSI字符串,僅僅是一個16位指針。它期望一個適當的16位Unicode字符串。如果你擺脫了類型轉換,代碼將無法編譯,並有很好的理由。不要使用類型轉換來避免編譯錯誤。

您必須先將輸出字符串數據轉換爲Unicode,然後才能爲其創建BSTR

您需要:

  • 使用MultiByteToWideChar()到您的最終char數據轉換爲wchar_t

    double _stdcall pll_dll(double* datain0, double* datain1, double* dataout0, double* dataout1, BSTR * str, int* str_len) 
    { 
        char c_buff[128] = {0}; 
        wchar_t w_buff[128] = {0}; 
        char * str0; 
        int len; 
    
        *dataout0 = *datain0 + 20; 
        *dataout1 = *datain1 + 30; 
    
        len = 30; 
        *str_len = len; 
    
        str0 = " Nice "; 
        len = sprintf(c_buff, "Hi %s \n", str0); 
    
        len = MultiByteToWideChar(CP_ACP, 0, c_buff, len, w_buff, 128); 
    
        SysReAllocStringLen(str, w_buff, len); 
    
        return 0; 
    } 
    
  • 重寫使用swprintf()代替sprintf()的代碼。

    double _stdcall pll_dll(double* datain0, double* datain1, double* dataout0, double* dataout1, BSTR * str, int* str_len) 
    { 
        wchar_t buff[128] = {0}; 
        wchar_t * str0; 
        int len; 
    
        *dataout0 = *datain0 + 20; 
        *dataout1 = *datain1 + 30; 
    
        len = 30; 
        *str_len = len; 
    
        str0 = L" Nice "; 
        len = swprintf(buff, L"Hi %s \n", str0); 
    
        SysReAllocStringLen(str, buff, len); 
    
        return 0; 
    }