2012-03-23 3 views
1

Mac OS에서 Word 2011 플러그인을 만들고 있습니다. 현재, 소켓 통신을 통해 다른 응용 프로그램에서 String을 검색하려면 VBA 매크로에 코드를 작성해야합니다. 기본적으로 Windows에서는 단순히 다른 응용 프로그램과 Socket 통신을 수행하고 VBA 매크로에 String 값을 반환하는 DLL을 만들 수 있습니다.Mac Office 2011 VBA 및 Dylib

그러나 Mac에서는 .dylib (C 언어)를 만들고 VBA를 사용하여 dylib와 통신 할 수 있습니다. 그러나 반환 문자열 문제가 있습니다. 내 간단한 C 코드는 다음과 같습니다. char * tcpconnect (char * arguments) {}

먼저 Chr (0) 문자가 항상 포함되어 있습니다. 둘째, 나는이 C 함수가 유니 코드 문자열을 처리 할 수 ​​없다는 것을 의심했다.

혹시 혹시이 경험이 있거나이 유사 사례가 있습니까?

감사합니다,

다윗은

+0

VBA -> .dylib -> 소켓 통신. – mashix

답변

1

내 원래의 게시물이의 malloc()를 사용하여() SysAllocStringByteLen을 모방하려는 시도했지만, Excel이 반환 된 메모리를 해제하려고 할 때이 오류가 발생합니다. 메모리를 할당 할 수 Excel을 사용하여이 문제를 해결하고, 적은 코드는 물론이고 예 :

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#define LPCSTR const char * 
#define LPSTR char * 
#define __declspec(dllexport) 
#define WINAPI 

char *saved_string = NULL; 
int32_t saved_len = -1; 

#define _CLEANUP if(saved_string) free(saved_string) 

__attribute__((destructor)) 
static void finalizer(void) { 
    _CLEANUP; 
} 

int32_t __declspec(dllexport) WINAPI get_saved_string(LPSTR pszString, int cSize) { 
    int32_t old_saved_len = saved_len; 
    if(saved_len > 0 && cSize >= saved_len) 
    strncpy(pszString, saved_string, saved_len); 
    if(saved_string) { 
    free(saved_string); 
    saved_string = NULL; 
    saved_len = -1; 
    } 
    return old_saved_len; 
} 

int32_t __declspec(dllexport) WINAPI myfunc(LPCSTR *pszString) { 
    int len = (pszString && *pszString ? strlen(*pszString) : 0); 
    saved_string = malloc(len + 5); 
    saved_len = len + 5; 
    sprintf(saved_string, "%s%.*s", "abc:", len, *pszString); 
    return saved_len; 
} 

가에, 그리고

gcc -g -arch i386 -shared -o test.dylib test.c 

으로 위를 컴파일 TEST.C에서

새 VBA 모듈을 사용하고 아래의 "test"를 실행하면 문자열 "hi there"앞에 "abc :"가 붙고 결과가 디버그 창에 출력됩니다.

Public Declare Function myfunc Lib "<colon-separated-path>:test.dylib" (s As String) As Long 
Public Declare Function get_saved_string Lib "<colon-separated-path>:test.dylib" (ByVal s As String, ByVal csize As Long) As Long 

Option Explicit 

Public Function getDLLString(string_size As Long) As String 
    Dim s As String 
    If string_size > 0 Then 
     s = Space$(string_size + 1) 
     get_saved_string s, string_size + 1 
    End If 
    getDLLString = s 
End Function 

Public Sub test() 
Debug.Print getDLLString(myfunc("hi there")) 
End Sub 
+0

아직도 왜 이것이 downvoted인지 모르지만 개선을위한 아이디어에 관심이있을 것입니다. – mwag