Передача строки из DLL в C #

0

У меня есть приложение С#, которое обращается к функциям из неуправляемой библиотеки C++ с использованием CLI DLL. Моя проблема заключается в том, что я не могу получить текст из библиотеки C++, который будет правильно передан в приложение С#. Код, который я имею до сих пор, выглядит следующим образом:

С#

[DllImport("Wrapper.dll", EntryPoint = "GetNameLength", CallingConvention = CallingConvention = CallingConvention.Cdecl)]
public static extern bool _GetNameLength( int index, out int size);
[DllImport("Wrapper.dll", CharSet = CharSet.Ansi, EntryPoint = "GetName", CallingConvention = CallingConvention.Cdecl)]
public static extern bool _GetName( out Stringbuilder name, int size, int index);

private void TestFunction()
{
    int size = 0;
    _GetNameLength(2, out size);
    StringBuilder str = new StringBuilder(size + 1);

    _GetName(out str, str.Capacity, 2);

    btnName.Text = str.ToString();
}

CLI

// In the header.
#define DllExport __declspec( dllexport)

extern "C" {
    DllExport bool __cdecl GetNameLength( int index, int& size);
    DllExport bool __cdecl GetName( char* name, int size, int index);
};


// In the '.cpp'.
bool __cdecl GetNameLength( int index, int& size) {
    if( gp_app == nullptr)
        return false;

    gp_app->GetNameLength( index, size);

    return true;
}

bool __cdecl GetName( char* name, int index, int size) {
    if( gp_app == nullptr)
        return false;

    const char* n = "";
    n = gp_app->GetName( index);

    name = new char[size];
    strcpy( name, n);

    return true;
}

C++

// In the header.
class App {
    void GetNameLength( int index, int& size);
    const char* GetName( int index);
};

// In the '.cpp'.
void App::GetNameLength( int index, int& size) {
    if( index >= 0 && index < gs_namesCount)
        size = strlen( gs_names[index]);
}

const char* App::GetName( int index) {
    if( index >= 0 && index < gs_namesCount)
        return gs_names[index];

    return nullptr;
}

Я могу отлаживать DLL, и я видел, что он правильно копирует имя, даже когда я просто использую name = const_cast<char*>( n) (и когда я использую строку вместо StringBuilder) но по какой-то причине это значение не возвращается к С# из DLL.

Я читал, что возможная причина заключается в том, что C++ может использовать символы ASCII, в то время как С# использует 16-битные символы, и что исправление для этого должно включать CharSet = CharSet.Ansi чтобы оно правильно упорядочивалось, когда оно возвращалось на С#, но это видимо, не помогло.

Может ли кто-нибудь сказать мне, что я делаю неправильно?


Решение:
Используйте public ref class вместо пространства имен и объявляйте функции, используя void Foo( [Out] String^ %name) гарантируя, что using namespace System::Runtime::InteropServices; Включено.

  • 0
    Мне кажется, что у вас есть несоответствие между заголовком и реализацией GetName в вашей части C ++ (один занимает один аргумент, два других).
  • 0
    Если вы используете C ++ / CLI, зачем возиться с экспортом DLL? Используйте ref class и вы можете использовать его так же, как C #.
Показать ещё 2 комментария
Теги:
dll
parameter-passing
c++-cli

1 ответ

2
Лучший ответ

Это говорит мне, что у вас есть управляемая DLL c++.

if( gp_app == nullptr)
    return false;

Если это так, вы можете экспортировать управляемый класс и использовать параметр String как метод.

Проверьте это: http://msdn.microsoft.com/library/windows/apps/hh699870.aspx

  • 0
    Я попытался использовать String и StringBuilder качестве параметров в моей оболочке, однако это означало, что я не смог назначить его с помощью __cdecl (мне пришлось использовать __clrdecl , я так думаю), что означало, что его нельзя было экспортировать для использования в моем Код C #
  • 0
    @Edward Используйте класс ref и вызывайте эти функции оттуда. Затем используйте конструктор String для создания управляемой строки.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню