ctypes 编辑

Draft
This page is not complete.

The ctypes object contains methods and predefined data types used to create and manage a library.

Method overview

CType ArrayType(type[, length]);
CData cast(data, type);
CType FunctionType(abi, returnType[, argType1, ...]);
CData Int64(n);
String libraryName(name);
Library open(libSpec);
CType PointerType(typeSpec);
CType StructType(name[, fields]);
CData UInt64(n);

Properties

PropertyTypeDescription
errnoNumberThe value of the latest system error. Similar to errno in libc, available on all platforms. Cannot be set.
winLastErrorNumber|undefinedThe value of the latest Windows error. Similar to GetLastError under Windows, available only for Windows. Cannot be set.

Constants

ABI constants

These constants are used to specify the ABI used to call a native function in the library.

ConstantDescription
default_abiCorresponds to cdecl; standard libraries use this ABI. You also use this for all system calls on Mac OS X and Linux.
stdcall_abiUsed for calling functions declared with stdcall on Windows. These functions' names are automatically mangled for you by js-ctypes.
winapi_abiUsed for calling Windows system functions. These are declared as stdcall on Windows, but do not have mangled names like those used by stdcall_abi above.

Predefined data types

Primitive types

These types behave the same on all platforms.

TypeDescription
int8_tSigned 8-bit integer.
uint8_tUnsigned 8-bit integer.
int16_tSigned 16-bit integer.
uint16_tUnsigned 16-bit integer.
int32_tSigned 32-bit integer.
uint32_tUnsigned 32-bit integer.
int64_tSigned 64-bit integer.
uint64_tUnsigned 64-bit integer.
float32_t32-bit floating-point value.
float64_t64-bit floating-point value.
Note: Some 64-bit values are outside the range of numeric values supported by JavaScript. Because of this, ctypes.int64 and ctypes.uint64 do not automatically convert to JavaScript numbers. Instead, they convert to objects of the wrapper types ctypes.Int64 and ctypes.UInt64, which are JavaScript objects rather than CData objects. See 64-bit integers for details.

Types that act like specific C types

These types are designed to work exactly like the corresponding type on the native platform.

TypeDescription
boolA Boolean type that behaves like the corresponding C type on the platform.
shortA short integer type that behaves like the corresponding C type on the platform.
unsigned_shortAn unsigned short integer type that behaves like the corresponding C type on the platform.
intAn integer type that behaves like the int C type on the platform.
unsigned_intAn unsigned integer type that behaves like the unsigned int C type on the platform.
long

A long integer type that behaves like the corresponding C type on the platform.

NOTE This automatically converts to an Int64 JavaScript object on all platforms, since it's unknown whether this is a 32-bit or 64-bit value. This is done for compatibility's sake.

unsigned_long

An unsigned long integer type that behaves like the corresponding C type on the platform.

NOTE This automatically converts to a UInt64 JavaScript object on all platforms, since it's unknown whether this is a 32-bit or 64-bit value. This is done for compatibility's sake.

long_longA integer type at least 64 bits wide.
unsigned_long_longAn unsigned integer type at least 64 bits wide.
floatA floating point value that behaves like the float type on the platform.
doubleA double-precision floating point value that behaves like the double type on the platform.

Character types

Character types are 8-bit values that behave like their C counterparts. They're similar to the int8_t and uint8_t types, except conversion is handled differently.

For example, ctypes.char.array(30)(str) converts the string str to UTF-8 and returns a new CData object of array type.

TypeDescription
char

A character type that behaves like the char C type on the platform.

signed_charA signed character that behaves like the char type on the platform.
unsigned_charAn unsigned character that behaves like the unsigned char type on the platform.

Types whose size varies depending on platform

Because it's unknown whether these values will be 32-bit or 64-bit, they are not automatically converted into JavaScript numbers. Instead, these convert into ctypes.Int64 or ctypes.UInt64 JavaScript objects; see 64-bit integers for details.

TypeDescription
size_tA platform-dependent size type.
ssize_tA platform-dependent size type.
intptr_tA platform-dependent integer representation of a pointer.
uintptr_tA platform-dependent unsigned integer representation of a pointer.

JavaScript characters

16-bit C Unicode characters are handled by js-ctypes using the jschar type.

TypeDescription
jscharA 16-bit unsigned character. This is different from uint16_t in that C jschar values are automatically converted into 1-character JavaScript strings. These are Unicode characters.

Special C types

These types represent C types that have special meanings.

TypeDescription
void_t

The special C type void. This can only be used as a return value type.

Note: You must use void_t, not void, since void is a keyword in JavaScript.
voidptr_tThe C type void *. This is a pointer to an indeterminate type of data.

Large integer types

Because JavaScript doesn't support large (64-bit) integers, js-ctypes provides two data types allowing access to 64-bit integer data.

TypeDescription
Int64A JavaScript object representing a 64-bit signed integer.
UInt64A JavaScript object representing a 64-bit unsigned integer.

Methods

cast()

Casts the specified CData object to a new type, returning a new CData object representing the value in the new type. See Type casting for details.

CData cast(
  data,
  type
);
Parameters
data
The CData object to type cast.
type
The type to which to cast the value. This can be one of the Predefined data types, or any user-defined types.
Return value

A new CData object representing the same data, but with the specified type.

libraryName()

Returns the correct platform-specific filename for a given library name (e.g. libnss3.dylib for nss3 on OS X.)

String libraryName(
  name
);
Parameters
name
The name of the library.
Return value

String containing the platform-specific filename of the library.

open()

Opens a library, specified by a pathname. The library is loaded from the specified full path, or, if a partial path is specified, from the appropriate library directory based on the platform on which the application is running. See Library search paths for more details.

Library open(
  libSpec
);
Parameters
libSpec
The native library to open, specified as a pathname string.
Return value

A Library object representing the opened library.

Examples

Example of StructType() on Windows

Let's say we need TB_BUTTON, this type needs to be created. So we look up on MSDN what the TB_BUTTON structures is (MSDN :: TB_BUTTON Structure) and it says it is:

typedef struct {
  int       iBitmap;
  int       idCommand;
  BYTE      fsState;
  BYTE      fsStyle;
#ifdef _WIN64
  BYTE      bReserved[6];
#else
#if defined(_WIN32)
  BYTE      bReserved[2];
#endif
#endif
  DWORD_PTR dwData;
  INT_PTR   iString;
} TBBUTTON, *PTBBUTTON, *LPTBBUTTON;

So now notice that if it's 64-bit process it's different than if it's 32-bit process. So we will figure that out and create the structure appropriately. This is what the final looks like:

var struct_TBButton;
if (ctypes.voidptr_t.size == 4 /* 32-bit */) {
  struct_TBButton = ctypes.StructType('TBButton', [
    {'iBitmap': ctypes.int},
    {'idCommand': ctypes.int},
    {'fbState': ctypes.unsigned_char},
    {'fsStyle': ctypes.unsigned_char},
    {'bReserved': ctypes.unsigned_char},
    {'bReserved2': ctypes.unsigned_char},
    {'dwData': ctypes.uintptr_t},
    {'iString': ctypes.intptr_t}
  ]);
}
else if (ctypes.voidptr_t.size == 8 /* 64-bit */) {
  struct_TBButton = ctypes.StructType('TBButton', [
    {'iBitmap': ctypes.int},
    {'idCommand': ctypes.int},
    {'fbState': ctypes.unsigned_char},
    {'fsStyle': ctypes.unsigned_char},
    {'bReserved': ctypes.unsigned_char},
    {'bReserved2': ctypes.unsigned_char},
    {'bReserved3': ctypes.unsigned_char},
    {'bReserved4': ctypes.unsigned_char},
    {'bReserved5': ctypes.unsigned_char},
    {'bReserved6': ctypes.unsigned_char},
    {'dwData': ctypes.uintptr_t},
    {'iString': ctypes.intptr_t}
  ]);
}
else {
  throw new Error("wut?!");
}

console.log(struct_TBButton.size);
// 20 on 32-bit, 32 on 64-bit if I'm not mistaken

There is another way to do this, we can use ArrayType, but example for this I don't know at this time.

Credit for this example is to nmaier (StackOverflow :: Getting TB_BUTTON is crashing and not working)

Example of cast and FunctionType on Windows

Components.utils.import("resource://gre/modules/ctypes.jsm");

var kernel = ctypes.open("kernel32.dll");
var HMODULE = ctypes.uint32_t;
var HWND = ctypes.uint32_t;
var LPCTSTR = ctypes.jschar.ptr;
var LPCSTR = ctypes.char.ptr;
var LoadLibrary = kernel.declare("LoadLibraryW", ctypes.winapi_abi, HMODULE, LPCTSTR);
var GetProcAddress = kernel.declare("GetProcAddress", ctypes.winapi_abi, ctypes.void_t.ptr, HMODULE, LPCSTR);

var hUser = LoadLibrary("user32");
var funcPtr = GetProcAddress(hUser, "MessageBoxW");

// Now we have a pointer to a function, let's cast it to the right type
var MessageBoxType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, LPCTSTR, LPCTSTR, ctypes.uint32_t]);
funcPtr = ctypes.cast(funcPtr, MessageBoxType.ptr);
funcPtr(0, "Test1", "Test2", 0);

Credit for this example is to Wladimir Palant (StackOverflow :: How to call a function using pointer in js-ctypes)

See also

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:129 次

字数:20505

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文