7

I have a function in a native DLL defined as follows:

#include <string>
void SetPath(string path);

I tried to put this in Microsoft's P/Invoke Interop Assistant, but it chokes on the "string" class (which I think is from MFC?).

I have tried marshaling it as a variety of different types (C# String, char[], byte[]) but every time I either get a NotSupportedException or a Native Assembly Exception (depending on what marshaling I tried).

As anyone ever done Native/Managed Interop where the native string class is used? Is there any way to Marshal this? Am I going to have to write my own Marshaler?

2
  • Great question; I was surprised it doesn't automagically work. msdn.microsoft.com/en-us/library/1b4az623.aspx Commented Oct 1, 2008 at 17:36
  • I was surprised too... there's no major reason it shouldn't...but it seems that STL is not going to work with it... Also...I would just change the function to use WCHAR, but it's not a DLL I can change. Commented Oct 1, 2008 at 17:48

3 Answers 3

6

Looks like you're trying to use the C++ standard library string class. I doubt that will be easy to Marshal. Better to stick with a char * and Marshal as StringBuilder. That's what I usually do. You'll have to add a wrapper that generates the C++ string for you.

Sign up to request clarification or add additional context in comments.

1 Comment

I was afraid of that...figures
2

The PInvoke interop assistant only supports C not C++. Unfortunately the MFC String class (CString I believe?) is C++ and won't work through the assistant. Instead try using the following

void SetPath(__in const WCHAR* path);

Comments

0

Yes. You can. Actually, not just std::string, std::wstring, any standard C++ class or your own classes can be marshaled or instantiated and called from C#/.NET.

The basic idea of instantiating a C++ object from .NET world is to allocate exact size of the C++ object from .NET, then call the constructor which is exported from the C++ DLL to initialize the object, then you will be able to call any of the functions to access that C++ object, if any of the method involves other C++ classes, you will need to wrap them in a C# class as well, for methods with primitive types, you can simply P/Invoke them. If you have only a few methods to call, it would be simple, manual coding won't take long. When you are done with the C++ object, you call the destructor method of the C++ object, which is a export function as well. if it does not have one, then you just need to free your memory from .NET.

Here is an example.

public class SampleClass : IDisposable
{    
    [DllImport("YourDll.dll", EntryPoint="ConstructorOfYourClass", CharSet=CharSet.Ansi,          CallingConvention=CallingConvention.ThisCall)]
    public extern static void SampleClassConstructor(IntPtr thisObject);

    [DllImport("YourDll.dll", EntryPoint="DoSomething", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
    public extern static void DoSomething(IntPtr thisObject);

    [DllImport("YourDll.dll", EntryPoint="DoSomethingElse", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
    public extern static void DoSomething(IntPtr thisObject, int x);

    IntPtr ptr;

    public SampleClass(int sizeOfYourCppClass)
    {
        this.ptr = Marshal.AllocHGlobal(sizeOfYourCppClass);
        SampleClassConstructor(this.ptr);  
    }

    public void DoSomething()
    {
        DoSomething(this.ptr);
    }

    public void DoSomethingElse(int x)
    {
        DoSomethingElse(this.ptr, x);
    }

    public void Dispose()
    {
        Marshal.FreeHGlobal(this.ptr);
    }
}

For the detail, please see the below link,

C#/.NET PInvoke Interop SDK

(I am the author of the SDK tool)

Once you have the C# wrapper class for your C++ class ready, it is easy to implement ICustomMarshaler so that you can marshal the C++ object from .NET.

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustommarshaler.aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.