Возврат из C # lib структуры, содержащей строку, в программу на C ++ - PullRequest
1 голос
/ 04 мая 2019

Я пытаюсь вызвать C # lib из программы на C ++. C # и это взаимодействие довольно новое для меня. Некоторые из коммуникаций были легкими, пока мне не пришлось столкнуться со струнами внутри конструкций. Я много читал и видел несколько примеров, но я не могу их воспроизвести и заставить их работать.

Я извлек код с примером отправки строки и получения строки, которая работает (_string_exchange). И метод _return_struct, который возвращает структуру со строкой, которая не работает. Отладчик не работает, когда я пытаюсь использовать переменную для std :: cout, с необработанным исключением из 0x00007FFFEA98A388 (KernelBase.dll). Console.WriteLine ничего не написал во время вызова.

Я полагаю, что это проблема сопоставления данных. Оба скомпилированы в выпуске x64 с использованием .NET Framework 4.6.1. Также я проверял с помощью sizeof () и Marshal.SizeOf (), чтобы убедиться, что оба имеют одинаковую длину байта. Также безуспешно пытался изменить символ проекта c ++ с юникода на многобайтовый.

Я видел подобные примеры, которые довольно хорошо объясняли все, но я не знаю, чего мне не хватает: Передача строк / массивов в структурах между C ++ / C #

Программа на C ++:

struct myStruct
{
    int myInt;
    double myDouble;
    bool myBool;
    char myString[64];
}; 

int main() {
    const TCHAR* pemodule = _T("F:\\PATH\\TO\\DLLsi\\LibCSharp.dll");
    HMODULE lib = LoadLibrary(pemodule);

    typedef LPCSTR(_cdecl *_string_exchange)(LPCSTR s);
    auto pString_exchange = (_string_exchange)GetProcAddress(lib, "_string_exchange");
    LPCSTR test = pString_exchange("LPCSTR test works fine");
    std::cout << test << std::endl;

    typedef myStruct(_cdecl *_return_struct)();
    auto pReturn_struct = (_return_struct)GetProcAddress(lib, "_return_struct");
    myStruct aStruct = pReturn_struct();
    std::cout << aStruct.myString << aStruct.myBool << " " << aStruct.myDouble << " " << aStruct.myInt << std::endl;

    return 0;
}

Библиотека C #:

namespace LibCSharp
{    
    public class Class1
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct myStruct
        {
            public int myInt;
            public double myDouble;
            [MarshalAs(UnmanagedType.U1)]
            public byte myBool;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string myString;
        }

        [DllExport]
        public static myStruct _return_struct()
        {
            Console.WriteLine("test");
            myStruct a;
            a.myInt = 3;
            a.myDouble = 2;
            a.myBool = 1;
            Console.WriteLine(a.myBool);
            a.myString = "Hello world! My values are: ";//28
            Console.WriteLine(a.myString);
            return a;
        }

        [DllExport]
        public static string _string_exchange(string s)
        {
            Console.WriteLine(s);
            return s;
        }
    }
}

Я также намерен в будущем сделать эту структуру массивом, надеюсь, когда она будет решена, у меня не возникнет много проблем, но любые комментарии заранее также приветствуются.

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 04 мая 2019

На первый взгляд кажется, что ваш код на c # выполняет маршалинг возвращаемой строки как tchar[64], что почти наверняка является юникодом wchar[64];в то время как ваш код C ++ ожидает, что ascii char[64] будет там.

Попробуйте изменить определение c ++ на

struct myStruct
{
    int myInt;
    double myDouble;
    bool myBool;
    TCHAR myString[64];
}; 
0 голосов
/ 04 мая 2019

Возможно, вам следует попробовать использовать именованные каналы для связи между двумя процессами. Это позволяет открывать поток и передавать любые байтовые массивы. Таким образом, вы можете сериализовать любой объект в массив и передать его.

Здесь работает решение для связи C ++ и C #.

Трубы более гибкие и независимы от системы, чем взаимодействие. Но, вероятно, менее эффективно ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...