代码之家  ›  专栏  ›  技术社区  ›  Steve M

在Java或.NET中封装C++ API

  •  4
  • Steve M  · 技术社区  · 16 年前

    有人成功地在Java或.NET中“打包”一个C++ API吗?我有一个应用程序,它提供了一个用于编写插件的C++ API。我想做的是从.NET或Java访问API。

    我需要使用COM,还是有更简单/更好的选择?

    7 回复  |  直到 16 年前
        1
  •  9
  •   oscarkuo    16 年前

    如果您有一个非常直接的方法签名(即采用并返回基元类型的方法,如int、char[]、void*……等),在.NET中这样做是相当容易的,并且仍然是可能的,但是在Java中使用JNI有点困难。

    但是,如果你的类方法使用了现代的C++编程技术,比如Boost共享指针和STL容器,那么这是一个完全不同的故事。在这种情况下,您需要非常小心地进行内存管理。

    编辑: 如果C++模板系统与C语言或Java泛型非常不同,因为它只是一个编译时机制,如果该方法具有C++模板参数,那就更有趣了。基本上,这意味着每次向模板参数传递不同的数据类型时,方法或类的签名都是不同的。这使得这种方法无法用C语言或Java语言来包装。

        2
  •  2
  •   jasonco    16 年前

    我认为你可能会要求类似于 Java Native Inferface 它允许您调用用C++语言编写的代码。但我从来没有用过。但你可能想看看。希望它有帮助。

        3
  •  1
  •   Community CDub    8 年前

    在Java方面,这里有很多选择。 this question 实际上,如果您的API可以装箱在一个DLL、COM或ActiveX对象中,那么它就相当接近于您要查找的内容。

    我个人使用JIntegra包裹API调用到Office(Word),并直接在Java中使用它。它确实需要一些黑客技术来获得所需的功能,但我们最终使其工作。fiddling实际上在单词方面,实际的集成相对容易。

        4
  •  1
  •   Filip Frącz    16 年前

    如果您要使用.NET,我建议您创建一个 C++/CLI wrapper . C++/CLI让你 mix the managed .NET code with native C++ code . 这种方法有一些诀窍,但在大多数情况下都非常有效。

    Wikipedia entry 还有一些很好的链接。

        5
  •  1
  •   justinhj    16 年前

    使用SWIG来处理JNI的东西可以包装CPP API并从Java中使用它非常无痛。

    这里有一个 SWIG tutorial

        6
  •  0
  •   Promit    16 年前

    我是第一作者 SlimDX . 它可能不是目前最大的开源互操作性项目,但在整个项目中有150k多条线,这是相当可观的。它是用C++/CLI编写的,它是一种微软开发语言,主要与C++兼容,它被设计成允许你构建包装器。它工作得很好,但警告说它只是窗户。单声道不能接受。我不知道这对你有多大的影响,但它可能是比COM更好的选择。不幸的是,你基本上需要想出很多技巧和窍门。我本想在博客上写下我们在Slimdx上使用的很多东西,但不知怎么的,我从来没有真正接触过它。

    在Java方面,我相信您必须使用JNI。祝你好运。我从来没有和任何一个和JNI一起工作的人交谈过,没有我们两个都笑过,以一种糟糕的“痛”的方式。

        7
  •  0
  •   Snazzer    16 年前

    我维护的软件是用C++实现的,但必须有多语言的接口,包括Java和.NET,还包括Delphi和VB6。另外,它必须在多个平台上工作(因此Java需要在UNIX上工作)。

    这样做的方法是使用单个dll,使用基元类型导出纯C函数。例如,给定一个类foo:

    long MY_EXPORT_FLAG FooCreate()
    {
        return (long)new Foo();
    }
    
    void MY_EXPORT_FLAG FooDestroy(long Handle)
    {
       delete (Foo*)Handle;
    }
    
    void MY_EXPORT_FLAG BarMethod(long Handle, const char* pStr1, long* pReturnValue)
    {
       *pReturnValue = ((Foo*)Handle)->BarMethod( pStr1 );
    }
    

    然后您的jni/.net/vb6/delphi代码实现特定于语言的类包装器,但调用这些C dll函数。每个类包装器将包含一个句柄,并将其传递到C函数中。

    这很好地工作,因为大多数语言倾向于使用C作为最低的公分母,只要您可以通过一个瘦的C API导出您的接口,您就可以为其他语言构建接口。

    我们在DLL中导出了C(而不是C++)API,因为跨平台的函数签名更加标准化。

    别忘了,在C语言和Java上,你必须处理多字节字符串编码,所以你应该知道如何将你的字符串转换为C++代码。这通常涉及到了解区域设置,或者您可以降低成本,只支持UTF-8。