如何在 Haxe 中使用 C/C++ 库(如 NCurses)
How to use a C/C++ library (like NCurses) in Haxe
我有一个用 Haxe 编写并通过 C++ (hxcpp) 编译为二进制文件的 cli。我想在其中使用 ncurses。我在 C 中使用过 ncurses,在 Haxe 中使用过 JS externs,但我无法弄清楚 Haxe/C++ 文档将两者联系在一起。
除了基本的 haxe 命令(即不构建文件等),我没有使用更多的 HXCPP 编译器,à la:
haxe -lib somelib -cp src --cpp bin/cpp path.to.Main
基本上,我可以使用所有自定义代码,但在外部代码上遇到困难。所以我不完全确定我在实现目标方面还缺少多少步骤。但我可以看到一些主要障碍。
- 如何在构建中包含 ncurses? IE。
cc -lncurses -o out [etc...]
在 Makefile 中。
- 如何包含正确的 extern 以允许 Haxe 完全无错误地编译。我看到的所有外部示例都涉及 class/namespace,但 NCurses 函数没有 class 或名称空间。我还没有找到关于裸外部函数的任何文档。
- 然后当然是在我实际的 Haxe 代码中正确包含 headers(或等效的 haxe 编译)的基础知识。
我知道这基本上是在要求 mini-tutorial,但我找不到可以放在一起实现此特定目标的示例或文档。
感谢您提供的任何帮助。
HXCPP 使用 xml-based build system。当您启动时 haxe -cp src --cpp bin/cpp path.to.Main
:
- Haxe 文件被转译为 C++,并在输出目录中生成
Build.xml
,即 bin/cpp/Build.xml
;
- 一切都由 HXCPP 构建,将新生成的项目
Build.xml
与 global default xml definitions 合并,然后调用编译器工具链。
您可以通过 @:buildXml
元数据 as described on the manual 将编译器标志、库注入 link、includes 目录等:
@:buildXml("
<target id='haxe'>
<lib name='-lncurses' if='linux'/>
<lib name='ncurses.lib' if='windows'/>
</target>
")
class Main{ ...
这些标签将附加到项目 Build.xml
。 The haxe
target is the default target. Keep in mind that every toolchain (MSVC, gcc, Xcode, etc.) has its own syntax. You can see examples in the build.xml of cross-platform low-level projects like Systools or Lime.
可以在haxe命令行中加入-D HXCPP_VERBOSE
查看实际启动了哪些命令:haxe -D HXCPP_VERBOSE -cp src --cpp bin/cpp path.to.Main
.
至于外部人员,更简单的情况是:
- 您在
@:cppFileCode()
块中使用#includes 和所需的一切编写 C++ 代码;你在这里写的所有内容都会粘贴到生成的 cpp 文件中 as-is;
- 您将在其中一个 haxe 类 上定义的一个 haxe 函数标记为
@:native("nameOfTheCppFunction")
,构建系统会将它们连接在一起。
@:cppFileCode("
#include <ncurses.h>
void nativeCppTest(){
/* here goes your ncurses code */
return;
}
")
class Main{
public static function main()
{
myCppTest();
}
@:native("nativeCppTest")
extern static function myCppTest():Void;
}
如果您打开生成的文件(在本例中为 bin/cpp/src/Main.cpp
),您会看到 haxe myCppTest()
调用已更改为其原始版本 nativeCppTest()
.
如果您想传递函数参数并接收 return 值,则必须将这些 using the cpp.*
standard library types 包装起来。例如:
@:cppFileCode("
#include <ncurses.h>
void nativeCppTest(const char* myString){
/* here goes your ncurses code */
return;
}
")
class Main{
public static function main()
{
myCppTest("print this");
}
@:native("nativeCppTest")
extern static function myCppTest(myString:cpp.ConstCharStar):Void;
}
有些转换是自动的(例如,在本例中,从常量字符串到 ConstCharStar),有些则需要显式 cast
;如果你需要传递指向 C++ 代码的指针,你可以通过 cpp.RawConstPointer.addressOf(<haxe object>)
(如果不是 const,则为 RawPointer
):
public static function main()
{
var myString:String = "print this";
myCppTest(cast cpp.RawConstPointer.addressOf(myString));
}
有用的参考资料:
我有一个用 Haxe 编写并通过 C++ (hxcpp) 编译为二进制文件的 cli。我想在其中使用 ncurses。我在 C 中使用过 ncurses,在 Haxe 中使用过 JS externs,但我无法弄清楚 Haxe/C++ 文档将两者联系在一起。
除了基本的 haxe 命令(即不构建文件等),我没有使用更多的 HXCPP 编译器,à la:
haxe -lib somelib -cp src --cpp bin/cpp path.to.Main
基本上,我可以使用所有自定义代码,但在外部代码上遇到困难。所以我不完全确定我在实现目标方面还缺少多少步骤。但我可以看到一些主要障碍。
- 如何在构建中包含 ncurses? IE。
cc -lncurses -o out [etc...]
在 Makefile 中。 - 如何包含正确的 extern 以允许 Haxe 完全无错误地编译。我看到的所有外部示例都涉及 class/namespace,但 NCurses 函数没有 class 或名称空间。我还没有找到关于裸外部函数的任何文档。
- 然后当然是在我实际的 Haxe 代码中正确包含 headers(或等效的 haxe 编译)的基础知识。
我知道这基本上是在要求 mini-tutorial,但我找不到可以放在一起实现此特定目标的示例或文档。
感谢您提供的任何帮助。
HXCPP 使用 xml-based build system。当您启动时 haxe -cp src --cpp bin/cpp path.to.Main
:
- Haxe 文件被转译为 C++,并在输出目录中生成
Build.xml
,即bin/cpp/Build.xml
; - 一切都由 HXCPP 构建,将新生成的项目
Build.xml
与 global default xml definitions 合并,然后调用编译器工具链。
您可以通过 @:buildXml
元数据 as described on the manual 将编译器标志、库注入 link、includes 目录等:
@:buildXml("
<target id='haxe'>
<lib name='-lncurses' if='linux'/>
<lib name='ncurses.lib' if='windows'/>
</target>
")
class Main{ ...
这些标签将附加到项目 Build.xml
。 The haxe
target is the default target. Keep in mind that every toolchain (MSVC, gcc, Xcode, etc.) has its own syntax. You can see examples in the build.xml of cross-platform low-level projects like Systools or Lime.
可以在haxe命令行中加入-D HXCPP_VERBOSE
查看实际启动了哪些命令:haxe -D HXCPP_VERBOSE -cp src --cpp bin/cpp path.to.Main
.
至于外部人员,更简单的情况是:
- 您在
@:cppFileCode()
块中使用#includes 和所需的一切编写 C++ 代码;你在这里写的所有内容都会粘贴到生成的 cpp 文件中 as-is; - 您将在其中一个 haxe 类 上定义的一个 haxe 函数标记为
@:native("nameOfTheCppFunction")
,构建系统会将它们连接在一起。
@:cppFileCode("
#include <ncurses.h>
void nativeCppTest(){
/* here goes your ncurses code */
return;
}
")
class Main{
public static function main()
{
myCppTest();
}
@:native("nativeCppTest")
extern static function myCppTest():Void;
}
如果您打开生成的文件(在本例中为 bin/cpp/src/Main.cpp
),您会看到 haxe myCppTest()
调用已更改为其原始版本 nativeCppTest()
.
如果您想传递函数参数并接收 return 值,则必须将这些 using the cpp.*
standard library types 包装起来。例如:
@:cppFileCode("
#include <ncurses.h>
void nativeCppTest(const char* myString){
/* here goes your ncurses code */
return;
}
")
class Main{
public static function main()
{
myCppTest("print this");
}
@:native("nativeCppTest")
extern static function myCppTest(myString:cpp.ConstCharStar):Void;
}
有些转换是自动的(例如,在本例中,从常量字符串到 ConstCharStar),有些则需要显式 cast
;如果你需要传递指向 C++ 代码的指针,你可以通过 cpp.RawConstPointer.addressOf(<haxe object>)
(如果不是 const,则为 RawPointer
):
public static function main()
{
var myString:String = "print this";
myCppTest(cast cpp.RawConstPointer.addressOf(myString));
}
有用的参考资料: