CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Threaded View

  1. #7
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: DllImport problems with c-style char arrays

    Like I said, why don't you cache the string like this :

    Code:
    void __stdcall GetString(LPSTR szString, int *pnLength)
    {
        static CString sString;
    
        if (szString == NULL)
        {
            sString = GetStringFromUdp();
            *pnLength = sString.GetLength();
        }
        else
        {
            const int nToCopy = min(*pnLength, sString.GetLength());
            ::strncpy(szString, sString, nToCopy);
            *pnLength = nToCopy;
        }
    }
    This only does the UDP call once.

    Not particularly nice though, it'll screw up if you ever wanted to make your app multithreaded : I'd prefer methods of the following kind :

    Code:
    void * __stdcall InitialiseCallResult()
    {
        CString *psString = new CString;
        *psString = GetFromUdp();
        return psString;
    }
    
    void __stdcall GetCallResult(void *pString, LPSTR szString, int *pnLength)
    {
        CString *psString = (CString *)pString;
    
        if (szString == NULL)
        {
            *pnLength = psString->GetLength();
        }
        else
        {
            const int nToCopy = min(*pnLength, psString->GetLength());
            ::strncpy(szString, *psString, nToCopy);
            *pnLength = nToCopy;
        }
    }
    
    void __stdcall ReleaseCallResult(void *pString)
    {
        CString *psString = (CString *)pString;
        delete psString;
    }
    
    // C#
    // C#
    public class Interop
    {
       [DllImport("MyDll.dll")]
       static private extern IntPtr InitialiseCallResult();
    
       [DllImport("MyDll.dll")]
       static private unsafe extern void GetCallResult(IntPtr pHandle, byte *pbData, ref int pnLength);
    
       [DllImport("MyDll.dll")]
       static private extern void ReleaseCallResult();
    
       static public string GetString()
       {
          IntPtr pHandle = InitialiseCallResult();
    
          int nLength = 0;
    
          GetCallResult(pHandle, null, ref nLength);
    
          byte [] abData = new byte[nLength];
    
          fixed (byte *pbData = abData)
          {
             GetCallResult(pHandle, pbData, ref nLength);
          }
    
          ReleaseCallResult(pHandle);
       }
    }
    Of course the real nice way of doing it is to use COM - but the above will suffice I would suggest.

    Darwen.
    Last edited by darwen; July 29th, 2005 at 03:49 PM.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured