A memory iteration highlighted by a marshal. AllocHGlobal ()

I have a third-party C library that has one of the exported methods:

#define MAX_INDEX 8
int GetStuff(IN char* index[MAX_INDEX], OUT char* buf, IN size_t size);

The first argument is filled with pointers to the buf argument, where certain lines are stored. Size indicates how long each line is expected to be in the buffer buffer. My C # P / Invoke method for this now looks like this:

[DllImport("Path/To/Dll", CharSet = CharSet.Ansi)]
private static extern int GetStuff(IntPtr indecies, IntPtr buf, Int32 size);

The C # P / Invoke method is private because I wrap its functionality with the public "getter" method, which handles memory allocation / deallocation for the caller. When I use this method in C ++, the iteration is actually quite simple. I'm just doing something like:

char* pIndecies[MAX_INDEX];
char* pBuffer = new char[MAX_INDEX * (256 + 1)]; // +1 for terminating NULL

GetStuff(pIndecies, pBuffer, 256);

// iterate over the items
for(int i(0); i < MAX_INDEX; i++) {
    if(pIndecies[i]) {
        std::cout << "String for index: " << i << " " << pIndecies[i] << std::endl;
    }
}

- , ++, , , , IntPtr , , , ++, , # Unicode, ASCII. # , ? :

IntPtr pIndecies = Marshal.AllocHGlobal(MAX_INDEX * 4); // the size of a 32-pointer
IntPtr pBuffer = Marshal.AllocHGlobal(MAX_INDEX * (256 + 1)); // should be the same
NativeMethods.GetStuff(pIndecies, pBuffer, 256);

unsafe {
    char* pCStrings = (char*)pIndecies.ToPointer();
    for(int i = 0; i < MAX_INDEX; i++) {
        if(pCStrings[i])
            string s = pCStrings[i];
    }
}

: " , ?" ? StringBuilder ? , 1:1 GetStuff(). , .

.

, Andy

+5
1

, , . :

[DllImport("Path/To/Dll", CharSet = CharSet.Ansi)]
private static extern int GetStuff(IntPtr[] index, IntPtr buf, Int32 size);
....
IntPtr[] index = new IntPtr[MAX_INDEX];
IntPtr pBuffer = Marshal.AllocHGlobal(MAX_INDEX * 256 + 1);
try
{
    int res = NativeMethods.GetStuff(index, pBuffer, 256);
    // check res for errors?
    foreach (IntPtr item in index)
    {
        if (item != IntPtr.Zero)
            string s = Marshal.PtrToStrAnsi(item);
    }
} 
finally
{
    Marshal.FreeHGlobal(pBuffer);
}

++.

+3

All Articles