мне нужно передать аргумент в небезопасное DllImported функции в виде:Как получить символ ** с помощью C#?
[DllImport("third_party.dll")]
private static extern unsafe int start(int argc, char** argv);
Я предполагаю, что это массив строк. Однако, когда я пытаюсь сделать следующее, я получаю сообщение «Невозможно преобразовать из строки [] в ошибку char **». Как я могу заставить это работать? Благодарю.
string[] argv = new string[] { };
start(0, argv);
EDIT 1: вопрос был отмечен как дубликат, но, глядя на возможный дубликат вопрос, я до сих пор не понимаю, как получить эту работу.
EDIT 2: Для дальнейшего обсуждения вопросов и требуемых параметров. Он похож на ваши стандартные параметры argc/argv (количество параметров, а затем значения параметров). Точно так же вы можете запустить c-программу: int main(int argc, char** argv);
Для этой конкретной проблемы я вообще не хочу передавать какие-либо аргументы (так что число равно 0).
EDIT 3: Я получил дополнительную информацию от поставщика сторонней библиотеки. Здесь:
- первый параметр является счетчиком аргументов
второй параметр представляет собой массив нулем строки- струны ANSI кодируются
РЕДАКТИРОВАТЬ 4: Заключительное редактирование с рабочим решением (по крайней мере, в моем случае). Я бы ответил на этот вопрос, но не могу, потому что этот вопрос отмечен как дубликат. Вот link на вопрос, который мне очень помог. В конце функция dll ожидает массив указателей на буферы с ANSI-строками. Итак, мой последний подход (основанный на связанном вопросе) был следующим. Создайте массив в памяти, чтобы удерживать указатели, затем выделяйте каждую строку в другом месте в памяти и указывайте указатели на те строки внутри первого массива указателей. Этот код работает в производстве:
[DllImport("third_party.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern int start(Int32 args, IntPtr argv);
public bool start(params string[] arguments)
{
int result;
if (arguments == null || arguments.Length == 0)
{
result = dll_system_startup(0, IntPtr.Zero);
}
else
{
List<IntPtr> allocatedMemory = new List<IntPtr>();
int sizeOfIntPtr = Marshal.SizeOf(typeof(IntPtr));
IntPtr pointersToArguments = Marshal.AllocHGlobal(sizeOfIntPtr * arguments.Length);
for (int i = 0; i < arguments.Length; ++i)
{
IntPtr pointerToArgument = Marshal.StringToHGlobalAnsi(arguments[i]);
allocatedMemory.Add(pointerToArgument);
Marshal.WriteIntPtr(pointersToArguments, i * sizeOfIntPtr, pointerToArgument);
}
result = start(arguments.Length, pointersToArguments);
Marshal.FreeHGlobal(pointersToArguments);
foreach (IntPtr pointer in allocatedMemory)
{
Marshal.FreeHGlobal(pointer);
}
}
return result == 0;
}
'char *' Я знаю, как это сделать, но 'char **' ...? Argh. – code4life
Согласен - вопрос на самом деле краткий.Я не сделал этого, поэтому я не могу ответить :) –
Я думаю, вам нужно использовать StringBuilder [] вместо строки [] – RomCoo