Problem with Win32::API and pointers

Ask a Question related to PERL Modules, Design and Development.

  1. #1

    Default Problem with Win32::API and pointers

    Hi,

    I'm working on a project and trying to use the Win32::API to call a
    DLL from Perl, but I have some problems. I'm using the last version
    of the API (0.41).

    I'll describe my problem. I hope someone can help me. The DLL I've
    been trying to call from Perl is the FTD2XX.dll from FTDI, a Library to
    communicate with a chip connected to the computer via USB. The thing is
    really simple, this is my code:

    #CODE
    STARTS******************************************** **********************************
    use Win32::API;

    Win32::API::Type->typedef( 'FT_HANDLE', 'PVOID' );
    Win32::API::Type->typedef( 'FT_STATUS', 'ULONG' );

    #FT_Open
    Win32::API->Import( 'FTD2XX', 'FT_STATUS FT_Open(int
    deviceNumber,FT_HANDLE *pHandle)' );

    #FT_Close
    Win32::API->Import( 'FTD2XX', 'FT_STATUS FT_Close(FT_HANDLE ftHandle)'
    );


    #Open port
    FT_Open(0,$ft_handle);

    #Close port
    $ft_status = FT_Close($$ft_handle);
    #CODE
    ENDS********************************************** *************************************

    This is how the functions and variables are defined in the .h file:

    ....
    typedef PVOID FT_HANDLE;
    typedef ULONG FT_STATUS;
    ....

    FTD2XX_API
    FT_STATUS WINAPI FT_Open(
    int deviceNumber,
    FT_HANDLE *pHandle
    );

    ....
    FTD2XX_API
    FT_STATUS WINAPI FT_Close(
    FT_HANDLE ftHandle
    );
    ....


    The function FT_Open should return FT_STATUS (this works) but also a
    pointer *pHandle to the Handle, which is to be used for the forthcoming
    operations to the port, like in the function FT_Close.

    But when I run the program, this is what I receive:

    "Perl Command Line Interpreter has encountered a problem and needs to
    close. We are sorry for the inconvenience."

    The problem is on the FT_Close function. If I comment it out, the
    program runs OK (FT_Open returns Status OK), so I'm pretty sure the
    problem has something to do with the handle. As I said, FT_Open should
    give a pointer to the handle (2nd argument) and the handle itself is to
    be used in FT_Close (only argument).

    I thing it should work with the API, because it is pretty much the same
    as in one of the examples in the API Documentation. But I can't get
    it to work. Someone sees an error or something missing in my code?
    Please tell me if you need more info from me or if you have any
    suggestions on how I can fix this. This is really important for me. I
    thank you very much in advance.

    jrgoody@googlemail.com Guest

  2. Similar Questions and Discussions

    1. Win32::API problem...
      Hello, i got problem with Win32:API module. I have instaled ActivePerl on windows 95 (i must use this one ;/ ) after this i have downloded binary...
    2. Problem with win32 installer for PG 8.0
      Hi, I installed beta 2 a couple of months ago, and today I installed RC 5 and it seems there is no way to tell the installer where to actually...
    3. Win32::ODBC problem
      I'm getting lots of "Use of uninitialized value in array element at C:/Perl/lib/Win32/ODBC.pm line 256." It seems that each matching row in the...
    4. Pointers
      Hello all, newbie here got a few questions: I am working with pointers and I sort of understand them and then I don't. I understand that instead...
    5. Another Win32::GuiTest problem
      I have my script working with one major problem. The SendKeys function only seems to work if the window is not "iconized" (minimized). For example:...
  3. #2

    Default Re: Problem with Win32::API and pointers

    [email]jrgoody@googlemail.com[/email] wrote:
    > Hi,
    >
    > I'm working on a project and trying to use the Win32::API to call a
    > DLL from Perl, but I have some problems. I'm using the last version
    > of the API (0.41).
    >
    > I'll describe my problem. I hope someone can help me. The DLL I've
    > been trying to call from Perl is the FTD2XX.dll from FTDI, a Library to
    > communicate with a chip connected to the computer via USB. The thing is
    > really simple, this is my code:
    >
    > #CODE
    > STARTS******************************************** **********************************
    > use Win32::API;
    >
    > Win32::API::Type->typedef( 'FT_HANDLE', 'PVOID' );
    > Win32::API::Type->typedef( 'FT_STATUS', 'ULONG' );
    >
    > #FT_Open
    > Win32::API->Import( 'FTD2XX', 'FT_STATUS FT_Open(int
    > deviceNumber,FT_HANDLE *pHandle)' );
    >
    > #FT_Close
    > Win32::API->Import( 'FTD2XX', 'FT_STATUS FT_Close(FT_HANDLE ftHandle)'
    > );
    >
    >
    > #Open port
    > FT_Open(0,$ft_handle);
    >
    > #Close port
    > $ft_status = FT_Close($$ft_handle);
    This looks wrong. You are treating $ft_handle like a reference to a perl
    scalar. But it contains the address of a void pointer.

    I think you have to dereference the pointer in $ft_handle, but I have no
    idea how to accomplish this with Win32::API. I googled for it, but nothing
    helpful came up.

    Thomas

    --
    $/=$,,$_=<DATA>,s,(.*),$1,see;__END__
    s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
    $_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
    '%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
    print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e. r^.>l^..>k^.-
    Thomas Kratz Guest

  4. #3

    Default Re: Problem with Win32::API and pointers

    Thomas Kratz wrote:
    > [email]jrgoody@googlemail.com[/email] wrote:
    >
    >> Hi,
    >>
    >> I'm working on a project and trying to use the Win32::API to call a
    >> DLL from Perl, but I have some problems. I'm using the last version
    >> of the API (0.41).
    >>
    >> I'll describe my problem. I hope someone can help me. The DLL I've
    >> been trying to call from Perl is the FTD2XX.dll from FTDI, a Library to
    >> communicate with a chip connected to the computer via USB. The thing is
    >> really simple, this is my code:
    >>
    >> #CODE
    >> STARTS******************************************** **********************************
    >>
    >> use Win32::API;
    >>
    >> Win32::API::Type->typedef( 'FT_HANDLE', 'PVOID' );
    >> Win32::API::Type->typedef( 'FT_STATUS', 'ULONG' );
    >>
    >> #FT_Open
    >> Win32::API->Import( 'FTD2XX', 'FT_STATUS FT_Open(int
    >> deviceNumber,FT_HANDLE *pHandle)' );
    >>
    >> #FT_Close
    >> Win32::API->Import( 'FTD2XX', 'FT_STATUS FT_Close(FT_HANDLE ftHandle)'
    >> );
    >>
    >>
    >> #Open port
    >> FT_Open(0,$ft_handle);
    >>
    >> #Close port
    >> $ft_status = FT_Close($$ft_handle);
    >
    >
    > This looks wrong. You are treating $ft_handle like a reference to a perl
    > scalar. But it contains the address of a void pointer.
    >
    > I think you have to dereference the pointer in $ft_handle, but I have no
    > idea how to accomplish this with Win32::API. I googled for it, but
    > nothing helpful came up.
    >
    > Thomas
    >
    I agree with Thomas -- a Perl dereference is not what is needed here.

    It has been a while since I messed with this sort of thing, but you
    might want to try something like the following:

    # >>>> begin code fragment

    # Open port
    $ft_handle = ' '; # Preallocate 4 bytes.
    FT_Open (0, $ft_handle);

    # Dereference handle
    $ft_handle = unpack ('L', $ft_handle);

    # Close port
    $ft_status = FT_Close ($ft_handle);

    # >>>> end code fragment

    This is based on some code I wrote a while back, which uses the older

    $obj = Win32::API->new (dll, entrypoint, [argument ...], return)

    syntax. I do not know that you need to switch to this syntax to use the
    "preallocate before, unpack after" technique. I also do not know the
    current state of Aldo Calpini's documentation, but I do recall
    considerable code bashing to figure out what worked.

    Tom Wyant
    harryfmudd [AT] comcast [DOT] net Guest

  5. #4

    Default Re: Problem with Win32::API and pointers

    Thank you all for your responses.

    I've tried Tom's suggestions, but I still have the same problem.

    I receive the same Windows message "Perl Command Line Interpreter has
    encountered a problem and needs to close. We are sorry for the
    inconvenience.", but this time here:

    $ft_handle = unpack ('L',$ft_handle);

    So it looks like it occurs the first time $ft_handle is used as
    argument to a function.

    I tried to print the following in different places (for debugging):
    print ".$ft_handle."; with the following results:

    At the beginning of the code: ..
    After $ft_handle = ' '; :
    .. .
    After $ft_status = $ft_open->Call(0,$ft_handle); : ..
    After $ft_handle = unpack ('L',$ft_handle); : Nothing,

    the program doesn't returns after calling unpack(). Any suggestions?
    Need more info? Should I try something else?

    Thanks a lot in advance.

    jrgoody@googlemail.com Guest

  6. #5

    Default Re: Problem with Win32::API and pointers

    [email]jrgoody@googlemail.com[/email] wrote:
    > Thank you all for your responses.
    >
    > I've tried Tom's suggestions, but I still have the same problem.
    >
    > I receive the same Windows message "Perl Command Line Interpreter has
    > encountered a problem and needs to close. We are sorry for the
    > inconvenience.", but this time here:
    >
    > $ft_handle = unpack ('L',$ft_handle);
    >
    > So it looks like it occurs the first time $ft_handle is used as
    > argument to a function.
    >
    > I tried to print the following in different places (for debugging):
    > print ".$ft_handle."; with the following results:
    >
    > At the beginning of the code: ..
    > After $ft_handle = ' '; :
    > . .
    > After $ft_status = $ft_open->Call(0,$ft_handle); : ..
    > After $ft_handle = unpack ('L',$ft_handle); : Nothing,
    >
    > the program doesn't returns after calling unpack(). Any suggestions?
    > Need more info? Should I try something else?
    Did you check that $ft_status reports a successful call to FT_OPEN?

    Perhaps someone at perlmonks ([url]http://perlmonks.org[/url]) or better still the
    perl-win32-users mailing list at ActiveState has better ideas. If you are
    very lucky, Aldo will still be reading the latter.

    Thomas

    --
    $/=$,,$_=<DATA>,s,(.*),$1,see;__END__
    s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
    $_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
    '%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
    print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e. r^.>l^..>k^.-
    Thomas Kratz Guest

  7. #6

    Default Re: Problem with Win32::API and pointers

    Well, thank you all. It works now!

    First of all, Tom's suggestions were right. It didn't work at the
    beginning because although I preallocated the memory for the reference
    and dereferenced the handle after the function call, as Tom explained,
    I was still using the new Win32::API syntax to import a function, using
    the intact C prototype.

    As I found out later, I had to use the "old" and "deprecated" method
    for importing a function, using the parameter list. These are excerpts
    of my (working) code:

    # begin code fragment

    use Win32::API;

    #FT_Open
    #Prototype: FT_STATUS WINAPI FT_Open( int deviceNumber, FT_HANDLE
    *pHandle);
    $ft_open = Win32::API->new('FTD2XX', FT_Open, 'NP', 'N');

    #FT_Close
    #Prototype: FT_STATUS WINAPI FT_Close( FT_HANDLE ftHandle );
    $ft_close = Win32::API->new('FTD2XX', FT_Close, 'N', 'N');


    #Open port
    $ft_handle_p = ' '; #Preallocate 4 bytes
    $ft_status = $ft_open->Call(0,$ft_handle_p);

    $ft_handle = unpack ('L',$ft_handle_p); #Dereference handle

    #Close port
    $ft_status = $ft_close->Call($ft_handle);

    # end code fragment

    Another interesting thing (and I think the cause of the problems using
    directly the C prototype when importing the function) is that if you
    look at the function prototypes, *pHandle (in FT_Open) and ftHandle (in
    FT_Close) are both declared as of type FT_HANDLE, which is defined in
    the header file as PVOID. However, in the case of FT_Open the function
    returns a pointer to the handle, while FT_Close expects the handle
    itself. So, in the parameter list of FT_Close you must have an 'N'
    (unsigned long) and not a 'P' (pointer), even if the fthandle is also
    a PVOID in the C declaration.

    Well, I hope this helps also, and again thanks a lot for the fast and
    very effective help!

    jrgoody@googlemail.com Guest

  8. #7

    Default Re: Problem with Win32::API and pointers

    [email]jrgoody@googlemail.com[/email] wrote:
    > Well, thank you all. It works now!
    >
    > First of all, Tom's suggestions were right. It didn't work at the
    > beginning because although I preallocated the memory for the reference
    > and dereferenced the handle after the function call, as Tom explained,
    > I was still using the new Win32::API syntax to import a function, using
    > the intact C prototype.
    >
    > As I found out later, I had to use the "old" and "deprecated" method
    > for importing a function, using the parameter list.
    I do not know that you "have" to use the old method - I just couldn't
    figure out how to use the new method. If someone knows how to do it the
    new way, I would love to see it.

    Glad to help.

    Tom Wyant
    harryfmudd [AT] comcast [DOT] net Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139