ນີ້ແມ່ນຄໍາສັ່ງສ້າງ-native-map ທີ່ສາມາດດໍາເນີນການໄດ້ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີໂດຍໃຊ້ຫນຶ່ງໃນຫຼາຍໆບ່ອນເຮັດວຽກອອນໄລນ໌ຂອງພວກເຮົາເຊັ່ນ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator
ໂຄງການ:
NAME
create-native-map - ຜູ້ສ້າງແຜນທີ່ C/C#
ສະຫຼຸບສັງລວມ
ສ້າງ-native-map [OptionS]* ASSEMBLY-FILE-NAME OUPUT-PREFIX
OPTIONS
--autoconf-header=HEADER
ຫົວ ໜ້າ ແມ່ນຊື່ໄຟລ໌ header ໃນ syntax ໂດຍປົກກະຕິໃຊ້ກັບ C #include
ຖະແຫຼງການ, eg #include or #include "ທ້ອງຖິ່ນ.h" .
ມະຫາພາກທີ່ມີຮູບແບບ Autoconf ແມ່ນສ້າງຂຶ້ນຈາກຊື່ລວມ, ແລະ a #include
ຄໍາສັ່ງແມ່ນຫໍ່ຢູ່ໃນ #ifdef block ສໍາລັບ Macro Autoconf ພາຍໃນ
ຜະລິດ .c ຍື່ນ.
ຍົກຕົວຢ່າງ, --autoconf-header= ຈະສ້າງລະຫັດ:
#ifndef HAVE_STDIO_H
#ລວມ
#endif /* ndef HAVE_STDIO_H */
--autoconf-member=ສະມາຊິກ
ລະບຸວ່າການເຂົ້າເຖິງໃດໆ ສະມາຊິກ ຄວນຈະຖືກຫໍ່ພາຍໃນ a #ifdef HAVE_MEMBER
block. ສະມາຊິກ ສາມາດເປັນ ຊື່ພາກສະຫນາມ ຫຼື ຊື່ຫ້ອງ . ຊື່ພາກສະຫນາມ
ການປະສົມປະສານ.
ຕົວຢ່າງ, ໃຫ້ຄໍາປະກາດ C#:
[Mono.Unix.Native.Map ("struct dirent")]
ໂຄງສ້າງ Dirent {
public long d_off;
}
ຫຼັງຈາກນັ້ນ --autoconf-member=d_off ຈະສ້າງລະຫັດທີ່ຄ້າຍຄືກັນກັບ:
int
ToDirent (ໂຄງສ້າງ Dirent * from, struct Dirent *to)
{
#ifdef HAVE_STRUCT_DIRENT_D_OFF
to->d_off = ຈາກ->d_off;
#endif /* ndef HAVE_STRUCT_DIRENT_D_OFF */
}
--exclude-native-symbol=SYMBOL
SYMBOL ເປັນ [DllImport] - ຫມາຍວິທີການທີ່ຄວນ ບໍ່ ມີຕົ້ນແບບທີ່ສ້າງຂຶ້ນ
ສໍາລັບມັນ.
--impl-header=ຫົວ
ໃສ່ກ #include ຖະແຫຼງການພາຍໃນທີ່ສ້າງຂຶ້ນ .c file for ຫົວ ໜ້າ .
ຍົກຕົວຢ່າງ, --impl-header= ສ້າງ
# ປະກອບ
--impl-macro=MACRO
ໃສ່ກ #ກໍານົດ ຖະແຫຼງການພາຍໃນທີ່ສ້າງຂຶ້ນ .c ຍື່ນ. ມາໂຄຣ ສາມາດບັນຈຸເປັນ = to
ແຍກຊື່ມະຫາພາກຈາກຄ່າມະຫາພາກ.
ຍົກຕົວຢ່າງ, --impl-macro=FOO=42 ສ້າງ
# ກໍານົດ FOO 42
--library=LIBRARY
ສ້າງຕົວແບບສໍາລັບ [DllImport] - ຫມາຍວິທີການທີ່ອ້າງອີງພື້ນເມືອງ
ຫ້ອງສະຫມຸດ ຫໍສະຫມຸດ ເຂົ້າໄປໃນການຜະລິດ .h ຍື່ນ.
--public-header=HEADER
ໃສ່ກ #include ຖະແຫຼງການພາຍໃນທີ່ສ້າງຂຶ້ນ .h file for ຫົວ ໜ້າ .
ຍົກຕົວຢ່າງ, --public-header= ສ້າງ
# ປະກອບ
--public-macro=MACRO
ໃສ່ກ #ກໍານົດ ຖະແຫຼງການພາຍໃນທີ່ສ້າງຂຶ້ນ .h ຍື່ນ. ມາໂຄຣ ສາມາດບັນຈຸເປັນ = to
ແຍກຊື່ມະຫາພາກຈາກຄ່າມະຫາພາກ.
ຍົກຕົວຢ່າງ, --public-macro=FOO=42 ສ້າງ
# ກໍານົດ FOO 42
--rename-member=FROM=TO
ນີ້ແມ່ນໃຊ້ໃນເວລາທີ່ ຈາກ ແມ່ນມະຫາພາກ C, ແລະດັ່ງນັ້ນຈຶ່ງຕ້ອງຖືກປ່ຽນແປງເພື່ອໃຊ້
ຢ່າງມີສະຕິ. ການອ້າງອີງທີ່ສ້າງຂຶ້ນທັງໝົດຕໍ່ກັບການເປັນຕົວແທນທີ່ມີການຈັດການຈະໃຊ້ ເຖິງ ແທນທີ່ຈະເປັນ
of ຈາກ .
ຕົວຢ່າງ, ໃຫ້ຄໍາປະກາດ C#:
[Mono.Unix.Native.Map ("struct stat")]
ໂຄງສ້າງສະຖິຕິ {
public long st_atime;
}
ແລະການໂຕ້ຖຽງ --rename-member=st_atime=st_atime_ , ທີ່ຜະລິດໄດ້ .h ໄຟລ໌ຈະ
ບັນຈຸ:
ໂຄງສ້າງສະຖິຕິ {
gint64 st_atime_ ;
};
(ຫມາຍເຫດການປ່ຽນແປງຊື່ພາກສະຫນາມ), ໃນຂະນະທີ່ການຜະລິດ .c ໄຟລ໌ຈະມີ:
ToStat (ໂຄງສ້າງສະຖິຕິ *ຈາກ, ໂຄງສ້າງສະຖິຕິ *ເຖິງ)
{
to->st_atime_ = ຈາກ->st_atime;
}
--rename-namespace=FROM=TO
ໂດຍຄ່າເລີ່ມຕົ້ນ, C "namespace" (ສັນຍາລັກ prefix) ແມ່ນ C# namespace; ປະເພດພາຍໃນ
C# namespace Mono.Unix.Native ຈະຢູ່ໃນ C "namespace" Mono_Unix_Native ທີ່ຢູ່ ການນໍາໃຊ້
--rename-namespace ເພື່ອແກ້ໄຂຄ່າເລີ່ມຕົ້ນ, e.g --ປ່ຽນຊື່-
namespace=Mono.Unix.Native=Mono_Posix .
ລາຍລະອຽດ
ສ້າງ-native-map ແມ່ນໂຄງການສໍາລັບສະຖານະການສະເພາະ: ການຮັກສາລະຫັດທີ່ເຄັ່ງຄັດ
ສົມທົບລະຫວ່າງ C ແລະ C# ໃນ sync ກັບກັນແລະກັນ, ອີງຕາມປະເພດ C#.
Platform Invoke ມີປະໂຫຍດພຽງແຕ່ຖ້າລະຫັດທີ່ຖືກຄຸ້ມຄອງຮູ້ປະເພດທີ່ແນ່ນອນແລະຮູບແບບຂອງທັງຫມົດ
ໂຄງສ້າງທີ່ບໍ່ມີການຈັດການມັນໃຊ້. ນີ້ແມ່ນປົກກະຕິແລ້ວກໍລະນີໃນ Windows, ແຕ່ວ່າມັນແມ່ນ ບໍ່ ກໍລະນີ
ໃນ Unix. ຍົກຕົວຢ່າງ, ໂຄງສ້າງ ລັດ ເຮັດໃຫ້ການນໍາໃຊ້ຂອງປະເພດທີ່ມີຂະຫນາດທີ່ຈະແຕກຕ່າງກັນຈາກ
platform to platform (ຫຼືແມ້ກະທັ້ງອີງໃສ່ມະຫາພາກ compiler ກໍານົດ!). ຍົກຕົວຢ່າງ, off_t
ປົກກະຕິແລ້ວເປັນຈຳນວນເຕັມ 32-bit ທີ່ໄດ້ເຊັນໃນເວທີ ILP32, ແຕ່ອາດຈະເປັນຈຳນວນເຕັມ 64-bit ທີ່ເຊັນແລ້ວ.
ຢູ່ໃນເວທີ LP64, ແຕ່ອາດຈະເປັນຈໍານວນ 64-bit ລົງນາມໃນເວທີ ILP32 ຖ້າ
_FILE_OFFSET_BITS macro ມີມູນຄ່າ 64. ໃນສັ້ນ, ທຸກສິ່ງທຸກຢ່າງມີຄວາມຍືດຫຍຸ່ນພາຍໃນ Unix,
ແລະລະຫັດທີ່ຖືກຄຸ້ມຄອງບໍ່ສາມາດຈັດການກັບຄວາມຍືດຫຍຸ່ນດັ່ງກ່າວ.
ດັ່ງນັ້ນ, niche ສໍາລັບ ສ້າງ-native-map : ສົມມຸດວ່າ ABI ຄົງທີ່ລະຫັດທີ່ຖືກຄຸ້ມຄອງສາມາດເປົ້າຫມາຍ,
ແລະສ້າງລະຫັດເພື່ອ "thunk" ການເປັນຕົວແທນທີ່ມີການຄຸ້ມຄອງໃຫ້ກັບ native ທີ່ສອດຄ້ອງກັນ
ຕົວແທນ. ນີ້ຈໍາເປັນຕ້ອງໄດ້ເຮັດສໍາລັບ ທຸກສິ່ງທຸກຢ່າງ ທີ່ສາມາດແຕກຕ່າງກັນລະຫວ່າງເວທີແລະ
ທຸງ compiler, ຈາກຄ່າ enumeration ( SIGBUS ມີມູນຄ່າ 10 ໃນ FreeBSD ແຕ່ 7 ສຸດ
Linux) ເພື່ອສ້າງໂຄງສ້າງສະມາຊິກ (ໃຫຍ່ເທົ່າໃດ off_t ?)
ສ້າງ-native-map ຈະກວດກາ ASSEMBLY-FILE-NAME ແລະອອກໄຟລ໌ດັ່ງຕໍ່ໄປນີ້:
OUTPUT-PREFIX.h
ປະກອບມີຄ່າ enumeration, class ແລະໂຄງສ້າງ declaration, delegate
ຖະແຫຼງການ, ແລະ [DllImport] - ຫມາຍວິທີການ (ຈາກຫ້ອງສະຫມຸດລະບຸໄວ້ໂດຍ
-- ຫ້ອງສະໝຸດ ) ພາຍໃນກອງປະຊຸມ ASSEMBLY-FILE-NAME .
OUTPUT-PREFIX.c
ປະກອບດ້ວຍການປະຕິບັດການນັບຈໍານວນແລະການປ່ຽນໂຄງສ້າງ
ປະຕິບັດຫນ້າ.
OUTPUT-PREFIX.cs
ປະກອບມີຫ້ອງຮຽນບາງສ່ວນ NativeConvert ປະກອບມີການແປພາສາ enumeration
ວິທີການ.
OUTPUT-PREFIX.xml
ສ້າງ stubs ເອກະສານ ECMA XML ສໍາລັບການແປພາສາ enumeration
ວິທີການໃນ OUTPUT-PREFIX.cs .
ສ້າງ-native-map ຕົ້ນຕໍຊອກຫາ MapAttribute -decorated ປະເພດ, ແລະການນໍາໃຊ້ຂອງສອງ
MapAttribute ຄຸນສົມບັດ:
ປະເພດພື້ນເມືອງ
ປະກອບດ້ວຍປະເພດ C ທີ່ສອດຄ້ອງກັນ. ມີປະໂຫຍດພຽງແຕ່ຖ້າໃຊ້ກັບຫ້ອງຮຽນ,
ໂຄງສ້າງ, ແລະທົ່ງນາ.
ສະກັດກັ້ນທຸງ
ເມື່ອລະບຸໄວ້ໃນສະມາຊິກຈໍານວນຂອງ a [ທຸງ] - ຈໍານວນທີ່ອອກແບບ
ປະເພດ, ປິດການ ນຳ ໃຊ້ ເຄື່ອງກໍາເນີດລະຫັດປົກກະຕິສະຫນັບສະຫນູນສໍາລັບການ enumeration bit-masking
ປະເພດ
ນີ້ແມ່ນເປັນປະໂຫຍດໃນເວລາທີ່ bitmask ແລະຂໍ້ມູນທີ່ບໍ່ແມ່ນ bitmask ຖືກເກັບໄວ້ພາຍໃນ
ປະເພດດຽວກັນ, ແລະການກວດສອບ bitmask ບໍ່ຄວນຖືກນໍາໃຊ້ສໍາລັບການທີ່ບໍ່ແມ່ນ bitmask
ຄຸນຄ່າ. ຕົວຢ່າງ: Mono.Unix.Native.FilePermissions.S_IFREG , ເຊິ່ງບໍ່ແມ່ນ
bitmask ມູນຄ່າ, ໃນຂະນະທີ່ຫຼາຍທີ່ສຸດຂອງ ການອະນຸຍາດໄຟລ໌ ປະກອບດ້ວຍຄ່າ bitmask (
FilePermissions.S_IRUSR , FilePermissions.S_IWUSR , ຯ ລະຯ )
ໄດ້ MapAttribute ຄຸນລັກສະນະສາມາດໄດ້ຮັບການລະບຸໄວ້ໃນຊັ້ນຮຽນ, ໂຄງສ້າງ, ຜູ້ແທນ, ພາກສະຫນາມ, ແລະ
ການນັບເລກ.
ຜູ້ແທນ
ການສ້າງລະຫັດສໍາລັບຜູ້ແທນບໍ່ສົນໃຈ MapAttribute.NativeType ຊັບສິນ, ແລະ
ສ້າງຕົວຊີ້ຟັງຊັນ ພິມປະເພດ ທີ່ກົງກັບຄໍາປະກາດຂອງຜູ້ແທນທີ່ດີທີ່ສຸດ
ເຂົ້າໄປໃນ .h ຍື່ນ.
ຍົກຕົວຢ່າງ,
namespace Foo {
[ແຜນທີ່]
string ຕົວແທນ MyCallback (string s);
}
ສ້າງ ພິມປະເພດ :
typedef char* (*Foo_MyCallback) (const char *s);
ຊັ້ນຮຽນແລະໂຄງສ້າງ
A [ແຜນທີ່] -decorated class ຫຼືໂຄງສ້າງຈະໄດ້ຮັບການປະກາດໂຄງສ້າງ C ພາຍໃນ
.h file:
[ແຜນທີ່]
ໂຄງສ້າງ Foo {
public int i;
}
ກາຍເປັນ
ໂຄງສ້າງ Foo {
public int i;
};
ຖ້າ MapAttribute.NativeType ຊັບສິນຖືກຕັ້ງ, ຈາກນັ້ນຟັງຊັນການປ່ຽນໃຈເຫລື້ອມໃສຈະເປັນ
ປະກາດພາຍໃນ .h ໄຟລ໌ແລະສ້າງພາຍໃນ .c file:
namespace Foo {
[ແຜນທີ່ ("ໂຄງສ້າງ")]
ໂຄງສ້າງສະຖິຕິ {
public uint st_uid;
}
}
ກາຍເປັນ
/* ໄຟລ໌ .h */
ໂຄງສ້າງ Foo_Stat {
unsigned int st_uid;
};
int
Foo_FromStat (ໂຄງສ້າງ Foo_Stat *from, struct stat *to);
int
Foo_ToStat (ໂຄງສ້າງ stat *to, sxtruct Foo_Stat *to);
/* ໄຟລ໌ .c */
int
Foo_FromStat (ໂຄງສ້າງ Foo_Stat * ຈາກ, ໂຄງສ້າງສະຖິຕິ * ເຖິງ)
{
memset (to, 0, sizeof(*to);
to->st_uid = ຈາກ->st_uid;
return 0
}
int
Foo_ToStat (ໂຄງສ້າງ stat *to, sxtruct Foo_Stat *to)
{
memset (to, 0, sizeof(*to);
to->st_uid = ຈາກ->st_uid;
return 0
}
ສໍາລັບຊັ້ນຮຽນ, ຟັງຊັນການແປງພຽງແຕ່ຈະຄັດລອກທົ່ງນາທີ່ປະກາດໃນຊັ້ນຮຽນ
ຕົວຂອງມັນເອງ. ຊ່ອງຂໍ້ມູນທີ່ຖືກປະກາດໄວ້ໃນຊັ້ນຮຽນຫຼັກຈະບໍ່ຖືກສຳເນົາ. (ນີ້ແມ່ນຍ້ອນວ່າ
ສ້າງ-native-map ບໍ່ຮູ້ວ່າວິທີການສືບທອດໄດ້ຖືກປະຕິບັດໃນ C. ເພາະສະນັ້ນ
ການຄັດລອກຊ່ອງຂໍ້ມູນຈາກຊັ້ນຮຽນຂອງພໍ່ແມ່ຖືກປະໄວ້ໃຫ້ຜູ້ໂທຂອງການແປງ
ຫນ້າທີ່.)
Fields ຖ້າພາກສະຫນາມ (1) ມີ MapAttribute ຄຸນລັກສະນະ, ແລະ (2) ມີ
MapAttribute.NativeType ຄຸນສົມບັດທີ່ກໍານົດໄວ້, ຫຼັງຈາກນັ້ນປະເພດພື້ນເມືອງທີ່ລະບຸຈະຖືກໃຊ້
ສໍາລັບການກວດສອບ overflow. ຍົກຕົວຢ່າງ:
namespace Foo {
[ແຜນທີ່ ("ໂຄງສ້າງ")]
ໂຄງສ້າງສະຖິຕິ {
[ແຜນທີ່ ("off_t")] ສາທາລະນະຍາວ st_size;
}
}
ສ້າງ
/* ໄຟລ໌ .h */
ໂຄງສ້າງ Foo_Stat {
gint64 st_size;
};
int
Foo_FromStat (ໂຄງສ້າງ Foo_Stat *from, struct stat *to);
int
Foo_ToStat (ໂຄງສ້າງ stat *to, sxtruct Foo_Stat *to);
/* ໄຟລ໌ .c */
int
Foo_FromStat (ໂຄງສ້າງ Foo_Stat * ຈາກ, ໂຄງສ້າງສະຖິຕິ * ເຖິງ)
{
_cnm_return_val_if_overflow (off_t, from->st_size, -1);
memset (to, 0, sizeof(*to);
to->st_size = ຈາກ->st_size;
return 0
}
int
Foo_ToStat (ໂຄງສ້າງ stat *to, sxtruct Foo_Stat *to)
{
_cnm_return_val_if_overflow (gint64, from->st_size, -1);
memset (to, 0, sizeof(*to);
to->st_size = ຈາກ->st_size;
return 0
}
ນີ້ແມ່ນເປັນປະໂຫຍດສໍາລັບການກວດສອບຄວາມຜິດພາດທີ່ດີກວ່າພາຍໃນຫນ້າທີ່ການແປງ.
MapAttribute.NativeType ແມ່ນຕ້ອງການສໍາລັບການນີ້ເນື່ອງຈາກວ່າບໍ່ມີວິທີອື່ນທີ່ຈະຮູ້ວ່າແມ່ນຫຍັງ
ປະເພດພື້ນເມືອງແມ່ນ (ໂດຍບໍ່ມີການວິເຄາະໄຟລ໌ສ່ວນຫົວຂອງລະບົບ...).
ການນັບເລກ
ສ້າງຕົວເລກ C ແລະ macros ສໍາລັບແຕ່ລະສະມາຊິກພາຍໃນ
ການນັບເລກ. To ແລະ From ຫນ້າທີ່ຍັງຖືກປະກາດຢູ່ໃນ .h ໄຟລ໌ແລະ
ປະຕິບັດຢູ່ໃນ .c ຍື່ນ.
ຍົກຕົວຢ່າງ,
namespace Foo {
[ແຜນທີ່]
enum Errno {
EINVAL
}
}
ຈະສ້າງດັ່ງຕໍ່ໄປນີ້ໃນ .h file:
enum Foo_Errno {
Foo_Errno_EINVAL = 0,
#define Foo_Errno_EINVAL Foo_Errno_EINVAL
};
int Foo_FromErrno (int ຈາກ, int *to);
int Foo_ToErrno (int ຈາກ, int *to);
ແລະສ້າງດັ່ງຕໍ່ໄປນີ້ໃນ .c file:
int
Foo_FromErrno (int from, int *to)
{
*to = 0;
ຖ້າ (ຈາກ == Foo_Errno_EPERM)
#ifdef EINVAL
{*to = EINVAL;}
#ອື່ນ
{errno = EINVAL; ກັບ -1;}
#ສຸດທ້າຍ
return 0
}
int
Foo_ToErrno (int from, int *to)
{
*to = 0;
#ifdef EINVAL
ຖ້າ (ຈາກ == EINVAL)
{*to = Foo_Errno_EPERM; ກັບຄືນ 0;}
#ສຸດທ້າຍ
ກັບຄືນ -1;
}
ລະຫັດທີ່ແຕກຕ່າງກັນຈະຖືກສ້າງຂື້ນຖ້າ enum ທີ່ຖືກຄຸ້ມຄອງແມ່ນ a [ທຸງ] - ອອກແບບ
enumeration (ບັນຊີສໍາລັບທຸງ bitwise), ແຕ່ນີ້ແມ່ນແນວຄວາມຄິດພື້ນຖານ.
ໄປສະນີ LISTS
ການຢ້ຽມຢາມ http://lists.ximian.com/mailman/listinfo/mono-devel-list ສໍາລັບລາຍລະອຽດ.
ເວັບໄຊຕ໌ ເວັບໄຊ
ການຢ້ຽມຢາມ http://www.mono-project.com ສໍາລັບລາຍລະອຽດ
ສ້າງ-native-map(1)
ໃຊ້ສ້າງແຜນທີ່-native-map ອອນໄລນ໌ໂດຍໃຊ້ບໍລິການ onworks.net