Link to home
Start Free TrialLog in
Avatar of AndyCapp922004
AndyCapp922004

asked on

DLL requires a char[]....

OK, I have a dll written in VC++5.0 which as one of the parameter requires a char[] reference which is expected to have been already allocated by the calling function.  

the function declaration looks like this

Declare Auto Function cspGetBarcode Lib "csp32.DLL" (ByRef stBarData As Char(), ByVal lgBarcodeNumber As Long, ByVal maxLength As Long) As Int16

and the call like this:

Dim strCode As String = New String(" ", 10)
code = cspGetBarcode(strCode, i, codeLength)

obviously the reference is not being passed as I expected as I end up with a string exactly the same as it was before the call.
I know that the marshaller has something to do with this and have tried using a stringBuiler object.  I can't seem to get that to work either.

Any ideas ..?

this must be a fairly common problem.

Mahna Mahna.
Avatar of KarunSK
KarunSK
Flag of India image

The String data type is immutable in .NET; which means that you cannot change the value in the string once assigned. Try this:

Declare Auto Function cspGetBarcode Lib "csp32.DLL"
(<MarshalAs(UnmanagedType.LPStr)> ByRef stBarData As StringBuilder,
  ByVal lgBarcodeNumber As Long,
  ByVal maxLength As Long) As Int16
Avatar of AndyCapp922004
AndyCapp922004

ASKER

Karun,

That was the same road I was going down... though the example i had was buiding the Declaration a little  different (I couldn't get it to work until trying yours).

To no avail. with any of the unmanaged types supported by stringBuilder...

I am trying those with String type instead ... no luck yet though.
I'm not even getting an error, just empty strings on the other end.
Everything else from the dll is good, quantity of values, status values etc, etc.

Did you try out LPTStr and LPWStr versions? (They stand for Ansi and Unicode encoding of the strings resply). This will take care of encoding differences, if any should exist.

Or, you can pass an array of chars as input and later do a ToString when it comes back.
yep.. tried those still get zip in return.  Tried an array of characters also.  

I dug through the cpp file included with the dll  (convenient).... here is the actual function.

/*******************************************************************
 *              CSP Data Get                                       *
 *******************************************************************/

/*
 ** long DLL_IMPORT_EXPORT cspGetBarcode(char szBarData[], long nBarcodeNumber, long nMaxLength)
 *
 *  FILENAME: C:\Symbol\Csp32Proj\Csp32\Src\Csp32.cpp
 *
 *  PARAMETERS:     szBarData[] is a character array the user has allocated
 *                  to hold the barcode data. The string will be null terminated.
 *                  nBarcodeNumber indicates which barcode stored in
 *                  the szCspBcString[] will be returned.
 *                  nMaxLength is the length of the allocated space including the
 *                  null terminator. If nMaxLength is set to DETERMINE_SIZE, the
 *                  function will return the length of the barcode without
 *                  copying any data.
 *
 *  DESCRIPTION:    This function copies the barcode data from szCspBcString[]
 *                  to szBarData[] for up to nMaxLength characters. If the
 *                  barcode is longer it will be truncated.
 *
 *  RETURNS:        > 0     length of the barcode including the NULL terminator
 *                  BAD_PARAM if the requested barcode does not exist
 */

NoMangle long DLL_IMPORT_EXPORT cspGetBarcode(char szBarData[], long nBarcodeNumber, long nMaxLength)
{
    long i;
    long nBarFound;
    long nBarLength;
   
    // make sure the requested barcode is valid...
    if (nBarcodeNumber < 0)
        return( BAD_PARAM );

    if (nBarcodeNumber >= nCspStoredBarcodes)
        return( BAD_PARAM );

    // OK, go find the barcode...
    i = 0;
    nBarFound = 0;
    while (nBarFound < nBarcodeNumber)
        {
        // Look for the null terminator separating the strings...
        while (szCspBarData[i++] != 0);
       
        // bump count to the next barcode...
        nBarFound++;
        }  

    // OK, we've got the barcode, so process it...
    nBarLength = strlen(&szCspBarData[i]) + 1;

    // did the user only request the string's length?
    if (nMaxLength > DETERMINE_SIZE)
        {
        // get the maximum number of characters to copy...
        nMaxLength = min(nBarLength,nMaxLength);

        // copy the barcode...
        memcpy(szBarData, &szCspBarData[i], nMaxLength);
       
        // and null terminate the string...
        szBarData[nMaxLength-1] = 0;
        }

    return(nBarLength);
}

This only tells me that the stringbuilder i was originally using should work.  Perhaps you'll see it  though?
Let me check this out and get back to you. Meanwhile, just an observation, I noticed that the function header comment says szCspBcString[] whereas the function uses szCspBarData[]. I hope this is not a bug.
ASKER CERTIFIED SOLUTION
Avatar of KarunSK
KarunSK
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you Karun,

I had to change all of the return types from the original .bas file to get anything to work at all.  At the time I couldn't understand why int16 was working and not int32.  As I it turns out it the same .bas (vb5 or 6) file set up all the necessary enumerations as VB Long instead of int32(not sure why I could not at receive as VB long though).

I have changed all instances of Long to Int32 and things are working perfectly.

I never considered the fact that the numeric parameters were the problem.  It makes crystal clear sense now though, that the string was never being copied over because of this.  Live and learn. Thanks again Karun, this will was my first attempt at an unmanaged dll import from VB.NET (actually first .dll intreraction altogether) and it is afterall a success!!!

Andy.
Here is a very good link that will help you further in using data types for Interoperability:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp09192002.asp