LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Import Shared Library Wizard doesn't understand wchar_t

I'm trying to import the shared library for the Microchip MCP2210 USB-to-SPI bridge chip.

The Import Shared Library Wizard can understand most of the header file, and creates most of the wrapper VIs.  But not all.

The problem is the Wizard doesn't understand the wchar_t data type.  It successfully imports all the functions that don't use wchar_t, and fails to import all the functions that do use wchar_t.

I know I need to type something into to preprocessing field of the Wizard to convert wchar_t to some data type that LabVIEW understands, but I can't figure it out, and I can't find any solutions in the knowledge base.  (Although there seems to be many people who have had similar problems.)

According to the docs from Microchip, wchar_t seems to be a 2-byte character.  For example, the function GetLibraryVersion uses "wchar_t  *version" to create a "pointer to a buffer string of 64 bytes (so it can accommodate max 30 wide characters)". 

I'd sure appreciate any help.  Thanks.

Message 1 of 8
(4,087 Views)

Steve,

I know this is a bit generic, but have you seen this document yet? It is a great place to start for all Import Shared Library Wizard questions.

http://zone.ni.com/reference/en-XX/help/371361N-01/lvhowto/trbl_import_sl/

The hyperlinks in the article lead to even more information on certain topics.

Let me know if that helps.

Brandon

0 Kudos
Message 2 of 8
(4,028 Views)

If wchar_t is a 2-byte value, then you can pass in an array of U16 in LabVIEW instead. I would ignore the wizard and create the by hand the functions you need that use a wide character (wchar_t). You could also edit a copy of the .h file before importing it, or make sure LabVIEW can find the include file that defines wchar_t (which should be referenced by your .h), or add a definition within the wizard to define wchar_t to some data type LabVIEW knows about.

 

I'm less certain of the conversion between that array and a string. Possibly, if you only expect to use standard ASCII, you could simply ignore one byte of each value, probably the high byte. If not, then I would search this forum for threads about Unicode, but LabVIEW's Unicode support is limited.

0 Kudos
Message 3 of 8
(4,019 Views)

Basically, the quickest solution would be to add somewhere in your header file a line:

#define wchar_t uint16_t

Another possibility that leaves your header file intact for use with C compilers would be to add in the Preprocessor Definitions textbox following definition:

wchar_t=uint16_t 

 

Rolf Kalbermatter
My Blog
Message 4 of 8
(4,009 Views)

I had not seen this page, or the other pages it links to.  Thanks.  I don't know why these didn't turn up in my searches.

Anyway,  I replaced "wchar_t" with "unsigned short" in my header file, and then the Wizard was able to import all the DLL functions.

One of the functions, OpenByIndex() wouldn't import before, but now it does.  And it seems to work.

BTW, now I'm having different problems: I just tried to use LabVIEW to set the internal flash memory in the MCP2210 chip, with the GPIO and SPI config settings, and it didn't work.  In fact, it set the both VID and PID to zero, and changed the serial number!  Tomorrow I'll try to fix the VID/PID/SN using the utility exe that Microchip provides for this chip.  I couldn't install it for some reason before, but I'll try again.  If that doesn't work, I may have to replace the chip.  I'm kicking myself for not using and Arduino instead of the MCP2210.

Message 5 of 8
(3,995 Views)

Thanks for the advice.  I think I fixed the problem by replacing "wchar_t" with "unsigned short" in the header file.  The Wizard imported all the DLL functions, and OpenByIndex() seems to work.  I can open and close handles to the device.  That was the only essential function that wouldn't import before.

It seems that Microchip was just using wchar_t as a 16-bit integer, not for any actual unicode text.  I'm an analog hardware engineer, not a software engineer, but this seemed lazy and short-sighted to me, since it causes portability issues.  (FYI, the MCP2210 data sheet is also really bad.  It completely omits critical info; for example, it says there are 4 SPI modes, but doesn't say one word about what these modes are, or how they differ.  Unbelievable!)

And since you mention converting an array to a string, I'll share this.  Some of the functions in this DLL send/receive an array of bytes through the SPI interface, but the function protocol just uses a pointer to a string.  So I just use the type cast vi to convert my byte array to a string.  Unfortunately, I can't say if it worked or not, because I'm having other issues, like the VID and PID suddenly being set to zero for no apparent reason!

Message 6 of 8
(3,992 Views)

In old school C programming there was only char to mean an 8 bit value (well C doesn't specify at all how many bits any basic data type should have, it only defines the datatypes in terms of

Smallest addressable unit of the machine that can contain basic character set. It is an integer type. Actual type can be either signed or unsigned. It contains CHAR_BIT bits.[3]

This may sound pretty strange nowadays but there did exist 9 bit, 12 bit and even 4 bit CPUs in the past and still do in some isolated embedded areas.

 

C was originally not meant to be a high level programming language but instead one that allowed programming as close to the bare metal of the CPU as possible without requiring assembly code programming. This was partly for performance reason but also in order to allow use of advanced features of the underlying CPU without restricting the compiler builder very much.

 

So in old C char was the only type to define both strings and byte arrays. This proved over time problematic as the C programming moved more and more from embedded programming into high level programming and so there were various extensions defined in the years after such as C89/C90, C95. C99, C11 and newer ones which refer to the ratification year 1989, 1995, 1999 and 2011 respectively.

 

C95 added wchar_t.h and in there the wide char definitions. Note that the size of wchar_t is implementation specific, under most Unix variants it is generally referring to 32 bit characters whereas under Windows and some embedded platforms it refers to 16 bit character points.

 

C99 added the stdint.h with new standard datatypes with the ending _t which allow to specify more exactly the size of a variable in terms of bit size across all the different platfoms and are all normed to 8 bit, since there are currently no CPUs with any commercial interest that are not based on 8 bit or a multiple thereof.

 

Another issue might be that the Microchip embedded compilers to use when developing for their embedded platforms doesn't or at least didn't in the past technically support the C99 standard. Microsoft Visual C didn't do that either for a long time after 1999 and still doesn't implement everything from C99. Microsoft only recently started to push support for new C but more so C++ standards to the point that they support substantial portions of them sometimes before they get official standards!

 

As to your typecasting a byte array into a string to pass to the DLL function I would rather define the Call Library Function parameter to be directly a byte array passed by its C data pointer. The Typecast (for Byte Array to String and vv) and the Byte Array to String conversion node are technically a NOP in LabVIEW with no runtime overhead since they don't really do anything at runtime, but only change the color of te wire so the syntax checker doesn't complain about incompatible wires. However avoiding the Typecast altogether helps making the diagram cleaner and the code more readable.

The only reason to keep it a string parameter would be if you needed zero padding. LabVIEW will append a zero byte to every string passed to a Call Library Node as C string pointer since LabVIEW uses internally Long Pascal strings that contain the length in front of the string and doesn't need a zero byte at the end. This padding does cost extra performance since LabVIEW may have to resize the string buffer in order to append this zero byte.

Rolf Kalbermatter
My Blog
Message 7 of 8
(3,981 Views)

Had the same problem with importing DLLs of MCP2210.

 

Import manager did not recognize the functions that used wchar_t. Replaced all wchar_t in the header file with unsigned short, after that import dll worked just fine. Tested most of the functions and now everything seems to be working as intended.

Be sure to use latest DLL v2.1 released by microchip. I am using unmanaged DLLx86 for Labview 2017 32bit.

 

Thanks to OP for asking the right question and rolfk for solving.

 

0 Kudos
Message 8 of 8
(3,725 Views)