هاسكل: كيف يمكنني الحصول على قيم # تحدد-د الثوابت؟

StackOverflow https://stackoverflow.com/questions/1029545

  •  06-07-2019
  •  | 
  •  

سؤال

في برنامج هاسكل، ما هي أفضل طريقة لاستخدام الثوابت المحددة في رؤوس C؟

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

المحلول

لهذه المهمة، hsc2hs بك صديق.

لمثال بسيط، دعونا الحصول على قيمة INT_MAX من limits.h .

$ cat >IntMax.hsc
module Main where

#include <limits.h>

c_INT_MAX = #const INT_MAX

main = print c_INT_MAX

ومع hsc2hs، يمكننا أن #include الرؤوس واستخدام القيم الثوابت مع التوجيه #const.

وبدلا من بناء من جهة، واستخدام كابال:

$ cat >intmax.cabal
Name:          intmax
Version:       0.0
Cabal-Version: >=1.2
Build-Type:    Simple

Executable intmax
  Main-Is: IntMax.hs
  Build-Depends: base

لاحظ أن على الرغم من أن اسم البرنامج الرئيسي هو IntMax.hsc، ونقطة خط Main-Is إلى IntMax.hs. عندما ينظر كابال لIntMax.hs لكن يجد IntMax.hsc، فإنه يغذي تلقائيا الأخير من خلال hsc2hs كجزء من الإنشاء.

$ cabal configure
Resolving dependencies...
Configuring intmax-0.0...

$ cabal build
Prerocessing executables for intmax-0.0...
Building intmax-0.0...
[1 of 1] Compiling Main             ( dist\build\intmax\intmax-tmp\IntMax.hs, dist\build\intmax\intmax-tmp\Main.o )
Linking dist\build\intmax\intmax.exe ...

$ ./dist/build/intmax/intmax
2147483647

ملحوظة التي سترغب لتفريق خطوط مع ثوابت متعددة. أقول كنت تجميع bitfield لتمريرها إلى FormatMessage . فأنت تريد أن تكتب كما

flags = #const FORMAT_MESSAGE_FROM_SYSTEM
        .|.
        #const FORMAT_MESSAGE_IGNORE_INSERTS

ووضع كل منهم في سطر واحد سيؤدي إلى أخطاء في بناء الجملة.

نصائح أخرى

وGHC يتحرك بعيدا عن -fvia-c ونحو -fasm كلما كان ذلك ممكنا.

والآثار الجانبية واحد هو أن البرنامج قد يكون ترجمة دون استخدام أي رؤوس C في كل شيء، حتى في وضع -fvia-c، وذلك للتأكد من أن تجميع النتائج متطابقة وظيفيا لشركة الخليج القابضة في وضع -fasm.

وهكذا فمن الضروري استخدام hsc2hs، c2hs، أو تشغيل preprocessors أخرى <م> قبل GHC تجمع المصادر.

وc2hs يدعم أصلا الثوابت enum ... انها كانت فترة من الوقت، ولكن أعتقد أن شيئا من هذا القبيل هو الصحيح.

#c
enum Foo = { Bar, Baz };
void something(enum Foo foo) {}
#endc

{#enum Foo#}

somethingBar = {#call pure something#} (cFromEnum Bar)

والثوابت #define'd هي علامة اصعب. لقد دائما نسخ فقط لهم مضمنة، أو استخدامها إضافي C لتحويل ثم إلى تتضمن التعدادات أو المتغيرات CONST.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top