указатель на void указатель
От: sergey2b ЮАР  
Дата: 02.04.20 20:58
Оценка:
Всем привет

Возможно я ошибся разделом но лучшего не нашел
Я сишник и мне надо сделать интерфейс к своему коду из C#

Подскажите пожалуйста как под windows в C#
задекларировать и вернуть void** из C кода
Re: указатель на void указатель
От: pilgrim_ Россия  
Дата: 02.04.20 21:31
Оценка: +1
Здравствуйте, sergey2b, Вы писали:

S>Всем привет


S>Возможно я ошибся разделом но лучшего не нашел

S>Я сишник и мне надо сделать интерфейс к своему коду из C#

S>Подскажите пожалуйста как под windows в C#

S>задекларировать и вернуть void** из C кода

Привет,

Приведи сигнатуру C-ишной функции, с указанием соглашения о вызове (cdecl/stdcall и тп).
И поясни что ты с этим void** собираешься делать из C# кода, возможно никаких void** и не понадобится.
Re[2]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 02.04.20 21:48
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Здравствуйте, sergey2b, Вы писали:


S>>Всем привет


S>>Возможно я ошибся разделом но лучшего не нашел

S>>Я сишник и мне надо сделать интерфейс к своему коду из C#

S>>Подскажите пожалуйста как под windows в C#

S>>задекларировать и вернуть void** из C кода

_>Привет,


_>Приведи сигнатуру C-ишной функции, с указанием соглашения о вызове (cdecl/stdcall и тп).

_>И поясни что ты с этим void** собираешься делать из C# кода, возможно никаких void** и не понадобится.


int open(const char* filename, void** hSrc)
Re[3]: указатель на void указатель
От: pilgrim_ Россия  
Дата: 02.04.20 21:59
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>>>Подскажите пожалуйста как под windows в C#

S>>>задекларировать и вернуть void** из C кода

_>>Привет,


_>>Приведи сигнатуру C-ишной функции, с указанием соглашения о вызове (cdecl/stdcall и тп).

_>>И поясни что ты с этим void** собираешься делать из C# кода, возможно никаких void** и не понадобится.


S>int open(const char* filename, void** hSrc)


Кхе, при такой скудной инфе можно так:

public static class Unsafe
{
    [DllImport("mydll.dll", CharSet = CharSet.Ansi)]
    public static extern int open(string filename, IntPtr hSrc);
}
Отредактировано 02.04.2020 22:00 pilgrim_ . Предыдущая версия .
Re[4]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 02.04.20 22:25
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Здравствуйте, sergey2b, Вы писали:


S>>>>Подскажите пожалуйста как под windows в C#

S>>>>задекларировать и вернуть void** из C кода

_>>>Привет,


_>>>Приведи сигнатуру C-ишной функции, с указанием соглашения о вызове (cdecl/stdcall и тп).

_>>>И поясни что ты с этим void** собираешься делать из C# кода, возможно никаких void** и не понадобится.


S>>int open(const char* filename, void** hSrc)


_>Кхе, при такой скудной инфе можно так:


_>
_>public static class Unsafe
_>{
_>    [DllImport("mydll.dll", CharSet = CharSet.Ansi)]
_>    public static extern int open(string filename, IntPtr hSrc);
_>}
_>


Надо добавить ref перед intptr
Но этотне сработает я уже пробовал перед тем как писать на форум
Сообщение об ошибки о несоответствии типов
Re[5]: указатель на void указатель
От: pilgrim_ Россия  
Дата: 02.04.20 22:40
Оценка: 9 (1)
Здравствуйте, sergey2b, Вы писали:

S>>>int open(const char* filename, void** hSrc)


_>>Кхе, при такой скудной инфе можно так:


_>>
_>>public static class Unsafe
_>>{
_>>    [DllImport("mydll.dll", CharSet = CharSet.Ansi)]
_>>    public static extern int open(string filename, IntPtr hSrc);
_>>}
_>>


S>Надо добавить ref перед intptr


Я же тебя cпросил, какое предполагаемое использование из С#, в общем случае никаких ref не надо, все что нужно средствами класса Marshal.Read/Write* ты можешь сделать с любым IntPtr (по сути void* как в C).

S>Но этотне сработает я уже пробовал перед тем как писать на форум

S>Сообщение об ошибки о несоответствии типов

Извини, но в телепата играть не буду, давай нерабочий код, починим..

>какое предполагаемое использование из С#


Еще раз, какой характер твоего void**, это In/Out (вероятно) чего то непонятного (?), или строго типизированная структура, которую проще всего передавать/использовать средствами самого .NET (просто объявив нужную структуру на C#).
Re[6]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 02.04.20 22:56
Оценка:
Здравствуйте, pilgrim_, Вы писали:


_>Еще раз, какой характер твоего void**, это In/Out (вероятно) чего то непонятного (?), или строго типизированная структура, которую проще всего передавать/использовать средствами самого .NET (просто объявив нужную структуру на C#).


спасибо за помощь

функция открывает файл и возращает указатель на структуру описывающую открытый файл,
есть десяток функций работы с этим файлом которые как ожидают этот указатель что бы знать с каим файлом проводить операцию


как запастной вариант я планировал возращать int номер индифицирующий номер структуры
Re[7]: указатель на void указатель
От: pilgrim_ Россия  
Дата: 02.04.20 23:03
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>функция открывает файл и возращает указатель на структуру описывающую открытый файл,

S>есть десяток функций работы с этим файлом которые как ожидают этот указатель что бы знать с каим файлом проводить операцию

Предполагается ли работа из C# с самой структурой (читать/изменять ее)?
Если нет, то гоняй туда/сюда просто IntPtr и все, те пусть для .NET это будет черный ящик.

S>как запастной вариант я планировал возращать int номер индифицирующий номер структуры


Тут не понял, но Сергей, лучше сразу описать in/out параметры детально, вне зависимости используемых ЯП, можешь обозвать их как P1, P2 если чего то опасаешься
Описать в смысле для читателей твоих постов, для адекватного ответа.
Отредактировано 02.04.2020 23:07 pilgrim_ . Предыдущая версия . Еще …
Отредактировано 02.04.2020 23:06 pilgrim_ . Предыдущая версия .
Re[6]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 02.04.20 23:10
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Извини, но в телепата играть не буду, давай нерабочий код, починим..


extern "C" __declspec(dllexport) int input_open( const char* filename, void** hSrc )


            [DllImport("avlib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
            public static extern int input_open(string filename, ref IntPtr hSrc );


protected IntPtr hSrc = new IntPtr();
DLL.input_open(fileName, ref hSrc)


в момент выполнения эксепшен на второй параметр функции hSrc примерно звучащий как — неправильное преобразование типов


мне нужна помошь как получить hSrc из сишного кода что бы использовать для дальнейших вызовов
Re[8]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 02.04.20 23:28
Оценка:
В C# с структурой не какой работы не производиться вся работа только в сишном коде
Re[7]: указатель на void указатель
От: vorona  
Дата: 03.04.20 08:05
Оценка: +1
Здравствуйте, sergey2b, Вы писали:

Возможно надо явно указать разрядность сборки x86/x64
Re[8]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 03.04.20 12:11
Оценка:
Здравствуйте, vorona, Вы писали:

V>Здравствуйте, sergey2b, Вы писали:


V>Возможно надо явно указать разрядность сборки x86/x64


x86 в этом плане должно быть все нормально
Re[7]: указатель на void указатель
От: pilgrim_ Россия  
Дата: 03.04.20 12:24
Оценка: 6 (1)
Здравствуйте, sergey2b, Вы писали:

S>
S>extern "C" __declspec(dllexport) int input_open( const char* filename, void** hSrc )


S>            [DllImport("avlib.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
S>            public static extern int input_open(string filename, ref IntPtr hSrc );


S>protected IntPtr hSrc = new IntPtr();
S>DLL.input_open(fileName, ref hSrc)

S>


Ну выглядит все норм, должно работать, ref лучше заменить на out, чтобы был четко ясен смысл параметра, но и с ref должно работать.

S>в момент выполнения эксепшен на второй параметр функции hSrc примерно звучащий как — неправильное преобразование типов


без минимального воспроизводимого примера сложно понять причину, по коду все норм.
Проверь на всякий случай соглашение о вызове в C-коде, хотя там скорее всего была бы другая ошибка.
Re: указатель на void указатель
От: alexzzzz  
Дата: 03.04.20 23:41
Оценка: +1 :))
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста как под windows в C#

S>задекларировать и вернуть void** из C кода

Почему бы так и не написать в C#:
void**
?
Re[3]: указатель на void указатель
От: _NN_ www.nemerleweb.com
Дата: 05.04.20 12:22
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>int open(const char* filename, void** hSrc)


А этот hSrc не нужно будет освобождать потом случайно ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: указатель на void указатель
От: sergey2b ЮАР  
Дата: 05.04.20 12:40
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, sergey2b, Вы писали:


_NN>
S>>int open(const char* filename, void** hSrc)
_NN>


_NN>А этот hSrc не нужно будет освобождать потом случайно ?



Нужно и я освобождаюьрессурсымсохраненгые в структуре в конце
Re[5]: указатель на void указатель
От: _NN_ www.nemerleweb.com
Дата: 05.04.20 12:47
Оценка: 41 (2) +1 -1
Здравствуйте, sergey2b, Вы писали:

S>Здравствуйте, _NN_, Вы писали:


_NN>>Здравствуйте, sergey2b, Вы писали:


_NN>>
S>>>int open(const char* filename, void** hSrc)
_NN>>


_NN>>А этот hSrc не нужно будет освобождать потом случайно ?



S>Нужно и я освобождаюьрессурсымсохраненгые в структуре в конце


Через try-finally ?
А надо через SafeHandle и тогда код будет красивым и правильным:

using Microsoft.Win32.SafeHandles;


 [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
 [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
    internal class SrcFileHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private MySafeFileHandle()
            : base(true)
        {
        }
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        override protected bool ReleaseHandle()
        {
            return closeHSRC(handle);
        }

       [DllImport("libMy")] extern static bool closeHSRC(IntPtr hSrc);
    }


class MyLib
{
  [DllImport("libMy", CharSet=CharSet.Ansi)] extern static int open(string filename, out SrcFileHandle hSrc);
}


https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle?view=netframework-4.8
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.