用Java或.NET封装C++ API

4

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

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

7个回答

9
如果您的方法签名非常简单(即,使用基本类型(例如int、char[]、void*等)作为参数和返回类型),在.NET中进行翻译相对容易,在Java中使用JNI也是可能的,但需要更多努力。
然而,如果您的类方法使用现代C++编程技术,例如boost共享指针和STL容器,则情况就大不相同了。在这种情况下,您需要非常小心地处理内存管理。
编辑: 如果该方法具有C++模板参数,则会更加有趣,因为C++模板系统与C#或Java泛型非常不同,它只是一个编译时机制。基本上,这意味着每次将不同的数据类型传递给模板参数时,该方法或类的签名都会不同。这使得无法在C#或Java中包装该方法。

2
我认为您可能在询问类似于Java Native Interface的东西。它允许您调用使用C++等语言编写的代码。虽然我从未使用过它,但您可能想要查看一下。希望能有所帮助。

2

1

在Java方面,这里有很多选择.. this question实际上非常接近您所寻找的,只要您的API可以被封装在DLL、com或activex对象中。

我个人使用了JIntegra来包装对办公室(Word)的API调用,并直接在Java中使用它。虽然需要一些修改才能获得所需的功能,但我们最终还是让它工作了。实际上,调整是在Word方面进行的,而实际集成相对容易。


1

使用SWIG来处理JNI相关的内容可以使得将cpp API进行封装并从Java中调用变得非常轻松。

这里有一个SWIG教程


0

我维护的软件是用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。


0

我是SlimDX的首席作者。它可能不是最大的开源互操作性项目,但在整个项目中有150K+行代码,相当可观。它使用C++/CLI编写,这是一种由微软开发的语言,与C++基本兼容,旨在允许您构建包装器。它非常好用,但需要注意的是它仅适用于Windows系统。Mono将无法使用它。我不知道这对您来说是否是一个问题,但它可能比COM更好。不幸的是,有很多技巧和诀窍,你基本上必须自己想出来。我打算写一篇关于我们在SlimDX中使用的许多技巧和诀窍的博客文章,但不知怎么的,我总是没能完成。

在Java方面,我认为你必须使用JNI。祝你好运。我从未听说过任何一个人使用JNI而没有我们两个都会以一种糟糕的“哎呀那很疼”的方式笑出声来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接