Interfacing C# and C Dll Files using pointers that are sometimes required null with const TCHAR*   500pts

Posted on 2006-05-02
Last Modified: 2010-05-18
I have a C dll that I am writing a .NET wrapper for. Other functions that don't involve string-like types work. If i try to pass it as a string back to the C dll, then it gives me a Stack Imbalance error. Same goes for uint, IntPtr, and char[]. Anyway, Here is the function declaration in the API manual:
HENTRY Open2(const TCHAR *pszPort)

And here is my DllImport & function (APILIB is a constant declared earlier)
[DllImport(APILIB, PreserveSig = true)]
private static extern HWKBENTRY Open2(ref char pszPort);

public static HWKBENTRY WkbOpen(string pszPort)
            byte[] arg2 = System.Text.Encoding.Default.GetBytes(pszPort);
            return Open2(ref arg2[0]);
This works... except for one problem. I need to be able to pass a null pointer. Passing a null does not work. Passing a ref to a 0 byte does not work. I'm pretty lost on this one,
Question by:wibuus
    LVL 2

    Accepted Solution

    Change the import to use:

    IntPtr pPort

    instead of

    char pszPort

    Then, to pass the string to the function:

    string testString = "TextBeforeCall";

    IntPtr pTestString = Marshal.StringToCoTaskMemAnsi("testString");

    Look at alternatives to StringToCoTaskMemAnsi() if this gives you problems.

    To retrieve text returned from an IntPtr:

    string textAfterFunctionCall = Marshal.PtrToStringAnsi(pTestString);

    Marshal.FreeCoTaskMem(pTestString); // Dont forget to do this!!

    To specify null, use IntPtr.Zero

    Be carefull of HWKBENTRY. I don't know what it is, but if you get the type wrong, your stack will go out of line.
    LVL 2

    Expert Comment

    Ahh, hold on.

    That is correct as far as correctly passing a string in is concerned (always free the memory afterwards). If you want to receive the string back, then thats a different story I think.

    The way I do it is to allocate a buffer to hold the returned string:

    string message = string.Empty;
    byte[] messageBuffer = new byte[MESSAGE_SIZE];
    GCHandle hMessageBuffer = GCHandle.Alloc(messageBuffer, GCHandleType.Pinned);
    IntPtr pMessageBuffer = hMessageBuffer.AddrOfPinnedObject();

    MarshalledFunctionCall(pMessageBuffer); // This is the unmanaged call

    message = Marshal.PtrToStringAnsi(pMessageBuffer);

    // message now holds a normal .NET string

    There are other ways of doing this I'm sure, but this works fine for me.

    If you want to pass a string into a function, have it modified and then read it back as an out parameter, then the solution is somewhere near to my first post, but exactly what it is I can't say - I never had that situation. Maybe you can write another C function in the lib to get around that situation and use 2 pointers instead of 1.

    Good luck!

    Author Comment

    Thanks a lot... that worked perfectly!
    LVL 2

    Expert Comment

    Glad to have been of help!

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Suggested Solutions

    Here we come across an interesting topic of coding guidelines while designing automation test scripts. The scope of this article will not be limited to QTP but to an overall extent of using VB Scripting for automation projects. Introduction Now…
    Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
    An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
    In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    14 Experts available now in Live!

    Get 1:1 Help Now