如何在Haxe中使用C/C++库(例如NCurses)

4
我有一个用Haxe编写并通过C++ (hxcpp)编译为二进制文件的CLI,我想在其中使用ncurses。我曾经在C语言中使用过ncurses,并且也在Haxe中使用过JS externs,但我无法确定如何使用Haxe/C++文档将两者连接起来。
除了基本的haxe命令(如没有build文件等),我还没有使用过HXCPP编译器,就像这样:
haxe -lib somelib -cp src --cpp bin/cpp path.to.Main

基本上,我可以处理所有自定义代码,但在外部方面遇到了困难。因此,我不确定我离目标还有多少步骤。但我能看到几个主要障碍。

  1. 如何在构建中包含ncurses?例如,在Makefile中使用 cc -lncurses -o out [etc...]
  2. 如何包含正确的外部文件,以允许Haxe编译而不出错。我看到的所有外部示例都涉及类/命名空间,但NCurses函数没有类或命名空间。我没有找到任何关于裸外部函数的文档。
  3. 然后当然还有将头文件包含在我的实际Haxe代码中的基础内容(或相当于haxe编译的方法)。

我知道这基本上是在寻求一个迷你教程,但我找不到可以组合起来实现此特定目标的示例或文档。

感谢您提供的任何帮助。

1个回答

2
HXCPP使用基于XML的构建系统。当你启动haxe -cp src --cpp bin/cpp path.to.Main时:
  1. Haxe文件被转译为C++,并在输出目录中生成一个Build.xml,即bin/cpp/Build.xml
  2. 然后由HXCPP构建所有内容,将新生成的项目Build.xml全局默认XML定义合并,然后调用编译器工具链。
你可以通过@:buildXml元数据注入编译器标志、链接库、包含目录等,如手册所述
@:buildXml("
    <target id='haxe'>
       <lib name='-lncurses' if='linux'/>
       <lib name='ncurses.lib' if='windows'/>
    </target>
")
class Main{ ... 

这些标签将被追加到项目的Build.xml文件中。haxe目标是默认目标。请记住,每个工具链(MSVC、gcc、Xcode等)都有自己的语法。您可以在跨平台低级项目(如Systools的build.xmlLime)中看到示例。
您可以在haxe命令行中添加-D HXCPP_VERBOSE以查看实际启动的命令:haxe -D HXCPP_VERBOSE -cp src --cpp bin/cpp path.to.Main
至于外部定义,较简单的情况是:
你可以在@:cppFileCode()块中编写包括#includes和其他必要内容的C++代码;这里编写的所有内容都会原封不动地复制到生成的cpp文件中; 你可以将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()
如果您想传递函数参数并接收返回值,您必须使用使用cpp.*标准库类型进行包装。例如:
    @: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),有些则需要显式的强制类型转换;如果你需要传递指向C ++代码的指针,可以通过 cpp.RawConstPointer.addressOf(<haxe object>)(如果不是const,则使用RawPointer)获得:
    public static function main()
    {
        var myString:String = "print this";
        myCppTest(cast cpp.RawConstPointer.addressOf(myString));
    }

有用的参考资料:

1
哦天啊,非常感谢!看到所有东西组合在一起现在让文档更加有意义了。这是一个非常有用的例子! - dmcblue

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