REA_ANDREW
REA_ANDREW

Reputation: 10764

How do I invoke this native method from C#

I want to invoke one/many functions of a native library but I am unsure on the type mappings. The function in particular I am currently trying is as follows, here is the small console app which I am spiking in:

extern char *tgetstr (const char *name, char **area);

And here is my attempt at mapping this to use in a .NET console. I get an error saying, trying to read or write protected memory.

class Program
{
    [DllImport("termcap.dll")]
    public static extern IntPtr tgetstr(IntPtr name, IntPtr area);

    static void Main(string[] args)
    {
        IntPtr ptr1 = new IntPtr();
        IntPtr a = tgetstr(Marshal.StringToCoTaskMemAnsi("cl"), ptr1);
        Console.WriteLine(Marshal.PtrToStringBSTR(a));
    }
}

TIA

Andrew

Upvotes: 2

Views: 1452

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283634

You need to pass your IntPtr by ref, so the function can overwrite it. Then you also need to free the string after you've copied it, hopefully the DLL provides a matching deallocation function. StringToCoTaskMemAnsi isn't helping you any either, it's just leaking memory.

The correct p/invoke declaration is probably

[DllImport("termcap.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr tgetstr(string name, ref IntPtr area);

Upvotes: 2

Paul Sonier
Paul Sonier

Reputation: 39480

You have to pin your ptr1.

GCHandle handle = GCHandle.Alloc(ptr1, GCHandleType.Pinned);

Upvotes: 0

A_Nabelsi
A_Nabelsi

Reputation: 2574

I haven't worked with unmanaged code since 3 years but I think you can do it by marking the method parameters with MarshalAs attribute. Check this article,

MSDN

Upvotes: 0

Related Questions