#c# #c #interop
#c# #c #взаимодействие
Вопрос:
Не удалось повторить строку
C :
#include lt;iostreamgt; #include lt;newgt; #include lt;cstringgt; extern "C" { int DataToDotNet(char* str, uint64_t amp;size); } int DataToDotNet(char* str, uint64_t amp;size){ size = 8; str = new char[size]; std::strcpy(str, "CString"); std::cout lt;lt; "Sent Value is " lt;lt; str lt;lt; 'n'; return 1; }
C#:
using System; using System.Text; using System.Runtime.InteropServices; namespace DotNetConsole { class Program { [DllImport("1.so",CallingConvention=CallingConvention.Cdecl)] private static extern int DataToDotNet([MarshalAs(UnmanagedType.LPStr)]StringBuilder str, ref ulong size); static void Main(string[] args) { StringBuilder str= new StringBuilder(); ulong size = 0; int k=DataToDotNet(str,ref size); Console.WriteLine(str.Length.ToString());//Prints 0 } } }
Также я использую ref(C#) и amp;(C ) для базового типа, есть ли лучший способ? Я не использую visual C . ОС-это Linux. Команда компилятора:
clang -pedantic-errors -Wall -Wextra -Weffc -Wsign-conversion -Werror -std=c 17 -fPIC -c -o 1.o 1.cpp clang -pedantic-errors -Wall -Wextra -Weffc -Wsign-conversion -Werror -std=c 17 -shared -v -o 1.so 1.o
Я поместил файл в net5 папки отладки. Любые ссылки/ссылки/советы по этой теме также приветствуются[Примечание: Я использую Linux, .Net 5, а не visual c ]
Комментарии:
1. Вместо всех этих назначений, почему бы и нет
std::strcpy(str, "CString");
? И вместо вызова функцииnew
почему бы не использовать обычныйnew[]
, как вstr = new char[size];
?2. Что касается одной серьезной проблемы, вы, кажется, забыли, что аргументы в C по умолчанию передаются по значению . Это означает, что значение, используемое в вызове, копируется в локальную переменную аргумента функции. Поэтому, когда вы назначаете
str
себе, вы изменяете только локальную переменнуюstr
. Исходное значение, используемое при вызове функции, не будет изменено. Вам нужно пройти по ссылке (как вы это делаете дляsize
).3. И вам, вероятно, нужно использовать
extern "C"
для этой функции, чтобы предотвратить искажение имени.4. лол, я использовал мэллока. Я использую extern, у меня он работал для типа char. Я понимаю, что для передачи строк требуется немного больше работы, чем для передачи символов.
5. Только
extern
илиextern "C"
? Это две совершенно разные вещи. Вам нужно определить функцию какextern "C" int DataToDotNet(char* str, uint64_t amp;size){ ... }
.