Это не проблема, что Marshal.AllocHGlobal выделяет больше указанного объема памяти. Ваш код страдает от другой и вполне вероятной фатальной проблемы.
open_socket(char *clientIpAddr_p)
ожидает указатель на C-стиль строку с нулевым символом в конце (также известную как строка с нулевым символом в конце, строка с нулевым символом или ASCIIZ). Однако ваш код C # создает буфер и заполняет его строковыми символами / байтами, не заканчивая его нулевым символом. Вполне возможно, что это приведет к аварийному завершению функции open_socket или неправильному поведению при поиске в памяти (начиная с адреса, указанного указателем) отсутствующего нулевого символа.
Возможное исправление будет довольно простым: выделите буфер размером clientIpAddr.Length + 1
с учетом завершающего нулевого символа. Терминатор нуля (нулевой байт) должен быть установлен явно, поскольку Marshal.AllocHGlobal не не инициализирует / заполняет выделенный буфер нулевыми байтами. Поскольку здесь мы имеем дело со строкой ASCII / ANSI, нулевой символ - это просто байт со значением ноль.
byte[] clientIpAddr = System.Text.Encoding.ASCII.GetBytes("127.0.0.1")
IntPtr client_ipAddr_p = Marshal.AllocHGlobal(clientIpAddr.Length + 1);
Marshal.Copy(clientIpAddr, 0, ipAddress_p, clientIpAddr.Length);
Marshal.WriteByte(client_ipAddr_p, clientIpAddr.Length, 0);
Хорошо, забудьте о коде, который я только что написал. ; -) * 1 021 *
Почему? Поскольку существует еще более простое «универсальное» решение проблемы, избавляющее вас от необходимости вручную выделять и заполнять буфер для строки с нулевым символом в стиле C: Marshal.StringToHGlobalAnsi
метод, который преобразует вашу строку .NET с IP-адресом непосредственно в соответствующую строку ANSI с нулевым символом в конце в стиле C.
string ipAddress = "127.0.0.1";
IntPtr client_ipAddr_p = Marshal.StringToHGlobalAnsi(ipAddress);
(Если функция open_socket не требует, чтобы строковый буфер, на который указывает clientIpAddr_p , продолжал существовать после его вызова, освободите выделенный буфер с помощью метода Marshal.FreeHGlobal
после вызова собственной функции независимо от того, был ли буфер выделен с помощью Marshal.AllocHGlobal или Marshal.StringToHGlobalAnsi .)