Вопрос

У меня есть функция в собственной библиотеке DLL, определенная следующим образом:

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

Я попытался поместить это в Microsoft P / Invoke Interop Assistant, но он блокирует класс "string" (который, я думаю, из MFC?).

Я пробовал маршалировать его как множество различных типов (C # String, char[], byte []), но каждый раз я получаю либо NotSupportedException, либо исключение собственной сборки (в зависимости от того, какой маршалинг я пробовал).

Кто-нибудь когда-либо делал собственное / управляемое взаимодействие, где используется собственный класс string?Есть ли какой-нибудь способ упорядочить это?Должен ли я написать свой собственный Маршалер?

Это было полезно?

Решение

Похоже, вы пытаетесь использовать класс string стандартной библиотеки C ++.Я сомневаюсь, что это будет легко организовать.Лучше придерживаться символа * и маршалировать как StringBuilder.Это то, что я обычно делаю.Вам нужно будет добавить оболочку, которая генерирует строку C ++ для вас.

Другие советы

Помощник по взаимодействию PInvoke поддерживает только C, а не C ++.К сожалению, класс MFC String (CString, я полагаю?) является C ++ и не будет работать через assistant.Вместо этого попробуйте использовать следующее

void SetPath(__in const WCHAR* path);

ДА.Ты можешь.На самом деле, не просто std::string, std::wstring, любой стандартный класс C ++ или ваши собственные классы могут быть маршалированы или созданы экземпляры и вызваны из C #/.NET.

Основная идея создания экземпляра объекта C ++ из .NET world заключается в выделении точного размера объекта C ++ из .NET, затем вызовите конструктор, который экспортируется из библиотеки DLL C ++ для инициализации объекта, тогда вы сможете вызвать любую из функций для доступа к этому объекту C ++, если какой-либо из методов включает другие классы C ++, вам также нужно будет обернуть их в класс C #, для методов с примитивными типами вы можете просто P / Вызвать их.Если у вас есть только несколько методов для вызова, это было бы просто, ручное кодирование не займет много времени.Когда вы закончите работу с объектом C ++, вы вызываете метод деструктора объекта C ++, который также является функцией экспорта.если в нем его нет, то вам просто нужно освободить свою память от .NET.

Вот один из примеров.

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);
    }
}

Для получения более подробной информации, пожалуйста, перейдите по ссылке ниже,

Пакет SDK для взаимодействия с C # / .NET PInvoke SDK

(Я являюсь автором инструмента SDK)

Как только у вас будет готовый класс-оболочка C # для вашего класса C ++, его легко реализовать ICustomMarshaler чтобы вы могли маршалировать объект C ++ из .NET.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top