2016-08-05 129 views
1

我有一个从Squeak生成的.c文件,我需要编译为一个dll作为插件使用,但我不知道如何。我试过搜索互联网,但我能找到的所有信息都是关于如何将c#和C++编译为dll的信息。已生成的代码如下:编译C代码到动态链接库

/* Automatically generated from Squeak on (13 July 2016 9:46:45 pm) */ 

#if defined(WIN32) || defined(_WIN32) || defined(Win32) 
#ifdef __cplusplus 
    #define DLLEXPORT extern "C" __declspec(dllexport) 
#else 
    #define DLLEXPORT __declspec(dllexport) 
#endif /* C++ */ 
#else 
#define DLLEXPORT 
#endif /* WIN32 */ 

#include "sqVirtualMachine.h" 

/* memory access macros */ 
#define byteAt(i) (*((unsigned char *) (i))) 
#define byteAtput(i, val) (*((unsigned char *) (i)) = val) 
#define longAt(i) (*((int *) (i))) 
#define longAtput(i, val) (*((int *) (i)) = val) 

#include <string.h> 

/*** Variables ***/ 
struct VirtualMachine* interpreterProxy; 
const char *moduleName = "TestPlugin 13 July 2016 (e)"; 

/*** Functions ***/ 
DLLEXPORT int primitiveAdd(void); 
DLLEXPORT int primitiveFetchString(void); 
DLLEXPORT int setInterpreter(struct VirtualMachine* anInterpreter); 

DLLEXPORT int primitiveAdd(void) { 
    int operand1; 
    int operand2; 
    int result; 

    operand1 = interpreterProxy->stackIntegerValue(1); 
    operand2 = interpreterProxy->stackIntegerValue(0); 
    if (interpreterProxy->failed()) { 
     return 0; 
    } 
    result = operand1 + operand2; 
    interpreterProxy->popthenPush(3, ((result << 1) | 1)); 
    return 0; 
} 

DLLEXPORT int primitiveFetchString(void) { 
    int in; 
    int i; 
    int count; 
    int resultOop; 
    char* src; 
    char* dst; 
    char s0[] = "zero"; 
    char s1[] = "non-zero"; 

    in = interpreterProxy->stackIntegerValue(0); 
    if (interpreterProxy->failed()) { 
     return 0; 
    } 
    if (in == 0) { 
     src = s0; 
    } else { 
     src = s1; 
    } 
    count = strlen(src); 
    resultOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), count); 
    dst = ((char *) (interpreterProxy->firstIndexableField(resultOop))); 
    for (i = 0; i <= (count - 1); i += 1) { 
     dst[i] = (src[i]); 
    } 
    interpreterProxy->popthenPush(2, resultOop); 
    return 0; 
} 

DLLEXPORT int setInterpreter(struct VirtualMachine* anInterpreter) { 
    int ok; 

    interpreterProxy = anInterpreter; 
    ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR; 
    if (ok == 0) { 
     return 0; 
    } 
    ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR; 
    return ok; 
} 

注:这只是TestPlugin代码;我实际上正在构建一个像这样的dll,以加快我吱吱声中运行缓慢的吱吱声代码的区域。

回答

1

您的第一站应该是OpenSmalltalk virtual machine repository。该存储库包含有关如何编译虚拟机及其插件的全面文档。如果你想分发你的插件与虚拟机,那么这可能是你需要的。

另一方面,您可以自己编译插件并将其复制到插件目录。虚拟机将尝试根据请求加载插件,并可以在插件目录位于其搜索路径中时找到它。要自己编译插件,您需要构建工具链。这可以是生成共享库的任何东西(Visual Studio,XCode,autotools等)。

有你需要记住一些事情:

  1. 编译为共享和通用
  2. 编译成32位
  3. 在C++的情况:导出符号,以防止名字改编

构建脚本的复杂性取决于您要编译的库。对于在VM编译期间生成的插件的相当复杂的构建脚本(对于Windows),您可以查看PharoVM使用的CMake script for libgit2

不幸的是,共享库编译没有银弹。随着图书馆及其用户的需求发生变化,构建过程及其复杂性也会发生变化。对于依赖关系尤其如此(例如,当使用pkg-config为所需的库搜索常用安装路径时)。然而,从你的代码来看,我认为它不应该是一个大问题。我的建议:花时间为您的插件创建一个CMake脚本。这可能比手动运行编译器更困难,但它可以作为编译文档,如果您需要在另一个平台上进行编译,这将是一个很大的帮助。