سؤال

أقوم بتطوير برنامج Haskell صغير يستخدم مكتبة ثابتة خارجية قمت بتطويرها في C ++. يصل إلى LIB من خلال FFI GHC (واجهة الوظائف الأجنبية). داخل هذه المكتبة أود القيام ببعض الإخراج إلى وحدة التحكم. ومع ذلك، هو ذلك تبدو بالنسبة لي مثل الجانب C ++ من الأشياء ليس لديه مقبض صحيح إلى Stdout لأن الإخراج لا يظهر على وحدة التحكم. إذن، أسئلتي هي:

  • هل يختطف GHC هذه الجداول الثلاثة (Stdout، Stdin، Stderr) أو Libstdc ++ ببساطة لا تهيئةها لأنني أربط مع GHC؟
  • هل تحتاج واردات FFI الخاصة بي إلى أن تكون "آمنة" إذا كتبوا إلى Stdout؟
  • كيف يمكنني تمرير Stdout إلى وظيفة C؟ هل يجب علي مجرد تمريرها مباشرة أو أحتاج إلى نوع ج؟

ملاحظات إضافية: أنا أربط libstdc ++ مباشرة إلى الملف القابل للتنفيذ (أي GHC -LSTDC ++ ...) الذي افترضني ساذج سيكون الطريقة الصحيحة للقيام بذلك. يبدو أن تعمل بشكل جيد

عدم اعطاء رأي: لا يزال جديدا جديدا في Haskell، لذلك خطوات الطفل في الوقت الحالي؛ ص

هل كانت مفيدة؟

المحلول

يبدو أن مشكلتك هي أنه لا يتم تهيئة libstdc ++. أنا لست متأكدا تماما لماذا - -lstdc++ يكفي على نظامي - ولكن انظر ما إذا كان يعمل في الاتجاه الآخر.

Main.hs:

{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
foreign export ccall "Main_main" main :: IO ()
foreign import ccall driver_callback :: IO ()
main = putStrLn "Now in Haskell" >> driver_callback

driver.cc:

#include <iostream>

extern "C" {
# include "HsFFI.h"

#  ifdef __GLASGOW_HASKELL__
#   include "Main_stub.h"
    extern void __stginit_Main(void);
#  endif

    void driver_callback(void) {
        std::cout << "Back in C++" << std::endl;
    }
}

int main(int argc, char **argv) {
    hs_init(&argc, &argv);
# ifdef __GLASGOW_HASKELL__
    hs_add_root(__stginit_Main);
# endif

    std::cout << "Starting in C++" << std::endl;

    Main_main();

    hs_exit();
    return 0;
}

تجميع:

$ GHC -C --MAKE Main [1 من 1] تجميع الرئيسية (Main.hs، Main.o) $ GHC --Make -N-HS-Main-LSTDC ++ Driver.cc الرئيسي الربط الرئيسي ... $ ./main. بدءا من C ++ الآن في Haskell مرة أخرى في C ++
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top