Для описания и вызова функций из обычных dll на c/c++ используется класс Marshal.
Можно выделить память, преобразовать строку, структуру в неуправляемую память и обратно.
В примере вызывается функция GetComputerName, которая заполняет выделенную в программе память, а затем результат преобразуется в string и выводится на консоль.
class Program
{
static void Main(string[] args)
{
// Выделение памяти из неуправляемой области
// Получаем обычный указатель для использования в c/c++ функциях
var pComputerName = Marshal.AllocHGlobal(256);
// Вызываем описанную внешнюю функцию
// Она будет работать непосредственно с памятью по указателю
int size = 256;
GetComputerName(pComputerName, ref size);
// Переводим результат в управляемый вид
var str = Marshal.PtrToStringUni(pComputerName);
Console.WriteLine(str);
// Обязательно освобождаем выделенную память
Marshal.FreeHGlobal(pComputerName);
Console.ReadLine();
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern void GetComputerName(IntPtr pComputerName, ref int size);
}