LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How can I get an unsigned char string with nulls from a dll into LabVIEW 6i?

Still cant run this VI because I dont have w32n50.dll, but ...

This is what I guessed, you are not "allocating" any space for your return packet. If you were in C, you would not pass "NULL" for a parameter and expect to get a value back in that parameter, would you? While its not exactly equivilent, its what you are trying to do in Labview. Allocate some memory space for the packet with a "variable" and then pass that variable to the function. (See attatched VI). The missing 4 bytes are there, but hidden, LabVIEW is using the first four bytes to determine the length of the packet array. Try the code in the attatched VI and let us know how it goes.
0 Kudos
Message 11 of 28
(1,473 Views)
I can't open your vi because it is saved in version 6.1 where I am using 6i. As a guess that you were allocating memory space using initialize array, I tried that on the input side of my dll call but it didn't work either. So I'm curious to see your solution if you could save it back to version 6i.

Thanks
0 Kudos
Message 12 of 28
(1,471 Views)
This is just hilarious.

1) Providing the w32n50.dll now makes LV crash when opening the VI.

2) Writing a brand new VI and calling the "three" functions in ListAdapters.dll crashes LabVIEW.

3) Only two functions are listed in the Call Library Function dropdown list, although your code references three functions in the dll.

Conclusion: Maybe you have larger issues than just allocating memory space.

Anyway, same VI as above attatched saved in LV6.0 version with an alternate method for allocating space if initialize array method does not work.
0 Kudos
Message 13 of 28
(1,471 Views)
The w32n50 dll must need the installation software. That dll came from RawEther, they might have some security on it. The dlls work in C, it's just LabVIEW that's causing problems.

So initializing my array to anything has the same result, the first 4 bytes are missing. I can't use the cluster because it is a char ** pointer and LV doesn't allow for this type--it just allows handles which returns the pointer, not the data.

Flattening the char** pointer to the unsigned byte array to a string results in a memory access crash. Adding the flatten to string function after I take the subset of the array just adds the length of the array before the data.

So is la
bView taking my char** pointer and overwriting the first 4 bytes to the length of the array and then just showing me the remainder of the array? I've noticed that if I try to exit the vi after a read it shows a memory access error and exits ungracefully. If I try to save before exiting it gives me an insane object error before exiting ungracefully.

Something else I tried, was to write my packet data to the 5th element of the unsigned char * array, and while the data prints in C, it doesn't come across in LabVIEW...

Those first 4 bytes are crucial, I can't believe LabVIEW is trashing them and my program...
0 Kudos
Message 14 of 28
(1,471 Views)
The w32n50.dll is fine. I can use the "IsWin2k" and "IsWin95" functions (even though I guessed at the params) with out crashing anything and I get reasonable replies. As soon as I use ListAdapters.dll, LV goes nuts. Me thinks, as with the VI from the first posting (relatively speaking) the DLLs you posted are corrupted too. How about you post some zipped and fresh DLLs and I will try to continue to help. As a sanity check, how about you try using the dlls you posted and see what happens.
0 Kudos
Message 15 of 28
(1,471 Views)
....


> So initializing my array to anything has the same result, the first 4
> bytes are missing. I can't use the cluster because it is a char **
> pointer and LV doesn't allow for this type--it just allows handles
> which returns the pointer, not the data.
>
....



> Those first 4 bytes are crucial, I can't believe LabVIEW is trashing
> them and my program...
>

This is one of those times when the type alone doesn't document the
interface that well. If the type were a char*, it would be for either
letting the DLL return a char, or for you to provide a buffer that the
DLL reads from, or for you to preallocate a buffer that the DLL will
write into. To tell the difference you have to find the documentation
of the function and hope they give details.

For a char**, this probably means that the DLL is allocating data and
returning the string to you. In otherwords, you are probably supposed
to provide a place for the DLL to return a char* (a string).

As you give the DLL different LV types, they always treat it the same
way and only give you four bytes that point to the string. While this
is close to a LStrHandle that LV uses, it isn't close enough, and there
is all sorts of damage being done to the datastructures. In all cases,
there is a memory leak of the string the DLL is allocating, and the
crashes with dataspace insanities and memory accesses mean that the DLL
is then writing over LV's data structures.

I don't have enough details to tell you the exact solution, but if
indeed the DLL is allocating a string and you are to hold onto it and
give it back, make the type of the DLL be an int32 by pointer. You will
not be able to see the string, but you can give it over to the DLL as
either the integer -- when they want it as a char*, and as an integer
pointer whenever they want it as a char** -- when they might resize it
and give you back a different pointer.

If you need to be able to read or affect the contents of the string,
then I think you will need a small DLL function where you pass in the
integer as well as a character count if the string is binary, and you
will also send in either a LV string handle or a presized LV string as a
string pointer. In the DLL function you copy the contents to the LV string.

Greg McKaskle
0 Kudos
Message 16 of 28
(1,471 Views)
Hi,

If you want to give this method a try, I'll send it to you (but I need your
mail address, attachments don't get through).

It works for me! It simply gets data from a pointer in memory...

Regards,

Wiebe.



"Wiebe@AIR" wrote in message
news:3d590467$0$94913$e4fe514c@dreader3.news.xs4all.nl...
> Hi,
>
> There is a third option:
>
> Use windows lstrcpyn from kernel32.dll. This copies a pointer to mem to a
> string, if configured correctlly.
>
> This still stops when a \00 is encountered. So if it stops, add \00 to the
> string, add the length of the string (incl. \00) to the pointer, and use
the
> new pointer to do the same. While doing this, concatinate the returned
> strings.
>
> Repeat until satisfied (enough chars have been returned, or a EOF is
found.
> The EOF can be anything).
>
>
> Regards,
>
> Wiebe.
>
>
>
> "SachaE" wrote in message
> news:50650000000500000037950000-1027480788000@exchange.ni.com...
> > Hi,
> > there's only two options I can think of, both requiring
> > modifications to the DLL.
> > Firstly (and easiest) is to return the data in the format of an array
> > of numbers (Unsigned 8 bit). You can then use the byte array to
> > string.vi inside LabVIEW to convert it to your desired format. You
> > should find that the NULLs (00) then appear correctly inside the
> > string - to prove it just put the byte array to string.vi down and
> > create the appropriate control and indicator. Fill in a few of the
> > array elements with say 65, 66, 00, 67, and 68 and you should see
> > (when run) AB CD in the string indicator - if you look at the '/'
> > codes view it should then be AB/00CD.
> >
> > The other option is to replace every NULL inside the .dll's returning
> > data to be another character - prefereably one that is never used. The
> > downside is that although the data will appear in LabVIEW complete,
> > you'll then have to strip out the replacement character before you
> > make use of the data.
> >
> > Hope that helps
> >
> > S.
>
>
0 Kudos
Message 17 of 28
(1,609 Views)
I'm not sure I follow Greg's response here (I need to study it more), but I am attaching a zip file with my vi and the necessary dlls. I've included 2 versions of the listAdapters dll, the first has the dll write data at the beginning of the array, the second (with a longer name) writes the array length in the first four bytes, and starts writing data at the fourth byte. This second dll reads, but does not display any data in LV. I really don't understand why LV will not read this data in with the second dll, I've tried writing zeros, Fs, and finally the array length (00 00 00 E6) in the first 4 bytes, but all fail to display.

Here are the
function prototypes of the functions in the listAdapters dll:

char * listAdapters (int * success1, int *numAdapters);

int readPacket (char * ndisName, int * packetLen, unsigned char * * packet);

int sendPacket (char * ndisName, int * packetLen, unsigned char * PacketData);

Thanks
0 Kudos
Message 18 of 28
(1,471 Views)
Zipping up attachments seems to be working if you could just do that. I'm interested in seeing your solution, but I don't know that I really want to replace nulls with another value because I don't know what value I would choose that would be reliably consistant.
0 Kudos
Message 19 of 28
(1,609 Views)
Try adding these files to your system32 directory as well. They came with the dll I am wrapping around.
0 Kudos
Message 20 of 28
(1,471 Views)