forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Разработка LIB (http://forum.boolean.name/forumdisplay.php?f=58)
-   -   Передача сложных данных (http://forum.boolean.name/showthread.php?t=20419)

RegIon 30.09.2016 19:51

Передача сложных данных
 
У препода заскок случился. Ему нужно в WPF вызывать DLL, в которой происходит отрисовка на OpenGL.
Костыль такой:

WPF -> Windows Form Host -> DLL(C++) -> OpenGL

На костыль пофиг. Как передавать сложные данные в DLL из C# ?

Данные типа структур:
Код:

Line {
    double x1;
    double y1;
    double x2;
    double y1;
    int thikness;
    int[3] rgb;
}

Text {
    string text;
    double x;
    double y;
    int[3] rgb;
}

??

h1dd3n 01.10.2016 14:06

Ответ: Передача сложных данных
 
Ну через PInvoke. Там можно же структуры передавать.
Или тебя интересует конкретно как int[3] в структуре передать?

RegIon 01.10.2016 20:06

Ответ: Передача сложных данных
 
Цитата:

Сообщение от h1dd3n (Сообщение 308894)
Ну через PInvoke. Там можно же структуры передавать.
Или тебя интересует конкретно как int[3] в структуре передать?

А, мне необходимо массив структур таких передать.
В принципе по Pinvoke много инфы. Разберусь.

h1dd3n 01.10.2016 21:43

Ответ: Передача сложных данных
 
Ты не понял мой вопрос про int[3]. Массивы в структурах/классах можно хранить 2 способами - как указатель на какой-то массив (скорее всего в куче), это самый обычный для C# способ:
struct A {
public int[] Coordinates;
}

А можно прямо в структуре:
unsafe struct A {
public fixed int Coordinates[3];
}

То есть в варианте 2 layout у структуры - 3 интежера, а в 1 варианте всего 1 указатель куда-то на массив int[]. Это важно для pinvoke т.к. при передаче структур там тупо память кусками копируется, так что надо чтобы совпадало с нативным вариантом.

RegIon 02.10.2016 07:48

Ответ: Передача сложных данных
 
А, это довольно таки важно.

RegIon 02.10.2016 16:56

Ответ: Передача сложных данных
 
h1dd3n, как пробросить массив такого (C#):
PHP код:

[StructLayout(layoutKind:LayoutKind.Sequential)]
        public 
struct GLLine
        
{
            public 
float x1;
            public 
float y1;
            public 
float x2;
            public 
float y2;
            public 
float thinkness;
            [
MarshalAs(UnmanagedType.ByValArraySizeConst 3)]
            public 
int[] color;

            public 
GLLine(Line line)
            {
                
x1 = (float)line.X1;
                
x2 = (float)line.X2;
                
y1 = (float)line.Y1;
                
y2 = (float)line.Y2;

                
color = new int[3] { 256,256,256};
                if(
line.Stroke is SolidColorBrush)
                {
                    
Color c = ((SolidColorBrush)(line.Stroke)).Color;
                    
color[0] = c.R;
                    
color[1] = c.G;
                    
color[2] = c.B;
                }
                
thinkness = (float)line.StrokeThickness;
            }
        }; 

в эту фунцию?
PHP код:

void GLAddLineArray(GLLine *line) {
    
lineBuffer.insert(lineBuffer.end(), lineline + (sizeof(line) / sizeof(line[0])));


Если просто писать:
PHP код:

[DllImport(DLL_PATHCallingConvention CallingConvention.Cdecl)]
        public static 
extern void GLAddLineArray(GLLine[] line); 

То ничего не работает, хотя если по одиночке структуру кидать - все нормально.
PHP код:

[DllImport(DLL_PATHCallingConvention CallingConvention.Cdecl)]
        public static 
extern void GLAddLine(GLLine line); 


h1dd3n 02.10.2016 21:50

Ответ: Передача сложных данных
 
Что должно делать это:
(sizeof(line) / sizeof(line[0])
?

RegIon 02.10.2016 22:12

Ответ: Передача сложных данных
 
Цитата:

Сообщение от h1dd3n (Сообщение 308903)
Что должно делать это:
(sizeof(line) / sizeof(line[0])
?

Что и делает - размер массива в единицах. Длина всего массива в байтах / размер структуры в байтах.
Как в примерчике.
http://www.cplusplus.com/reference/v...vector/insert/

h1dd3n 02.10.2016 22:24

Ответ: Передача сложных данных
 
Цитата:

Сообщение от RegIon (Сообщение 308905)
Что и делает - размер массива в единицах. Длина всего массива в байтах / размер структуры в байтах.
Как в примерчике.
http://www.cplusplus.com/reference/v...vector/insert/

А вот и нет. sizeof дает тебе размер выделенной памяти, но line это аргумент типа GLLine* то есть указатель, и sizeof не дает тебе размер всего "массива" он дает тебе размер указателя.

http://stackoverflow.com/questions/4...th-of-an-array

1 ответ внимательно читаем.

RegIon 02.10.2016 22:30

Ответ: Передача сложных данных
 
Цитата:

Сообщение от h1dd3n (Сообщение 308907)
А вот и нет. sizeof дает тебе размер выделенной памяти, но line это аргумент типа GLLine* то есть указатель, и sizeof не дает тебе размер всего "массива" он дает тебе размер указателя.

http://stackoverflow.com/questions/4...th-of-an-array

1 ответ внимательно читаем.

По этой причине и терпеть не могу C/C++, придется еще и размер передавать, хотя я вообще не понимаю как маршаллер тогда работать должен (по идее структуры передаются по значению, а тут указатель) , но теперь работает.
Еще пришлось в параметр атрибут [In] добавить

h1dd3n 03.10.2016 19:51

Ответ: Передача сложных данных
 
Цитата:

Сообщение от RegIon (Сообщение 308909)
По этой причине и терпеть не могу C/C++, придется еще и размер передавать, хотя я вообще не понимаю как маршаллер тогда работать должен (по идее структуры передаются по значению, а тут указатель) , но теперь работает.
Еще пришлось в параметр атрибут [In] добавить

А что не так с маршаллером?
Зачем атрибут [In]?

RegIon 03.10.2016 23:18

Ответ: Передача сложных данных
 
Цитата:

Сообщение от h1dd3n (Сообщение 308936)
А что не так с маршаллером?
Зачем атрибут [In]?

1 - Порой не понимаю принципы работы.
2 - На всякий случай, много примеров нашел еще, где массивы с этими атрибутами передаются или возвращаются.

Цитата:

Аргументы, передаваемые по значению (например, аргументы input/In), передают при вызове функции копию переменной аргумента. Таким образом, эта копия переменной ведет себя как отдельная локальная переменная - она существует только в теле функции, и может быть внутри функции изменена, и при этом все изменения никак не повлияют на исходную переменную, которая была передана в функцию. С другой стороны аргументы, передаваемые по ссылке, передаются как оригинал, т. е. все изменения переданной переменной, если эти изменения сделает функция, сохранятся после завершения работы функции. Таким образом, вызывающий код увидит, что случилось с переменной внутри функции.
http://microsin.net/programming/pc/m...ple-types.html

h1dd3n 04.10.2016 19:54

Ответ: Передача сложных данных
 
Вообще лучше всего работать с указателями, то есть 1% кода (того кода который непосредственно имеет отношение к интеропу) пишешь с unsafe модификатором, не трахаешь себе мозг, все работает так как и ожидается. Остальные 99% пишешь на безопасном C#.

RegIon 04.10.2016 21:55

Ответ: Передача сложных данных
 
Цитата:

Сообщение от h1dd3n (Сообщение 308960)
Вообще лучше всего работать с указателями, то есть 1% кода (того кода который непосредственно имеет отношение к интеропу) пишешь с unsafe модификатором, не трахаешь себе мозг, все работает так как и ожидается. Остальные 99% пишешь на безопасном C#.

Он не компилирует. А флаги компиляции менять лень.
Кстати, все работает, почти.

Извращался изрядно.

RegIon 05.10.2016 09:48

Ответ: Передача сложных данных
 
Это нормально, что из DLL не работают?:
  • Исключения
  • I/O - ofstream/ifstream вообще молчат. Как логировать например??


Часовой пояс GMT +4, время: 09:04.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot