试图从Tcl传递指向API函数的指针

时间:2014-04-02 19:01:20

标签: c pointers tcl

我试图编写一个Tcl脚本来与FTDI USB设备(Windows平台)连接。我从FTDI API获得了一个带有单个输入参数的函数,但是一个名为“FT_GetDeviceInfoDetail'让我感到悲伤。

API函数调用如下:

FT_STATUS FT_GetDeviceInfoDetail (DWORD dwIndex, LPDWORD lpdwFlags, LPDWORD lpdwType, LPDWORD lpdwID, LPDWORD lpdwLocId, PCHAR pcSerialNumber, PCHAR pcDescription, FT_HANDLE *ftHandle)

其中LPDWORD,PCHAR和FT_HANDLE都是指向不同大小的内存空间的指针。

使用ffidl,我指定函数调用如下:

ffidl::callout _GetDeviceInfoDetail {uint32 pointer-var pointer-var \
            pointer-var pointer-var pointer-var pointer-var \
            pointer-var} uint32 \
        [ffidl::symbol $dll FT_GetDeviceInfoDetail]

这里有趣的地方。在Tcl中,为了将所有指针参数传递给API,我设置如下变量:              设置 variablename [二进制格式s 0]

当我调用该函数时,我为所有指针传递变量名称(即' foo',NOT' $ foo')并且(有些奇迹般地)函数返回一个' OK'状态。在这一点上,理论上,我传入的变量的内容将包含一些二进制字符串格式的数据。

然后我尝试重新构建'通过执行以下操作来实现二进制数据的字符串表示:

[binary scan $foo s outstring]

此时Windows介入并告诉我" Tclsh已停止工作"。

我怀疑该函数正在覆盖一个或多个变量的内存空间,但我不知道如何处理它。到目前为止,或许我想到的最好的想法是为Tcl编写一个C扩展,它将调用API,填充数据结构,然后以某种方式将结构传递回Tcl。

有人能指出我在纯Tcl中执行此操作的方法吗? (抱歉,双关语;我无法抗拒!)

2 个答案:

答案 0 :(得分:0)

我的ffidl有点生疏所以忍受我。我怀疑是因为你正在移交设置为:

的变量名
set varname [binary format s 0]

lpSerialNumber和lpDescription字段导致覆盖。这两个字段都可以大到16个字节。对于这些字段,初始化为16字节的空字符串的变量可能有效,即

set serno [string repeat "\0" 16]
例如,

应该为您提供lpSerialNumber字段所需的空间。无论如何,在这种情况下我会尝试。

答案 1 :(得分:0)

在使用各种二进制格式选项后,我发现如果我“设置foo [二进制格式xn]”(其中“foo”是我想要创建的指针,“n”是其中的字节数分配空间),然后将名称foo作为函数调用中的指针传递,该函数似乎正确工作(至少Tcl解释器不会崩溃!)。