0

I have a C dll that exports a function that looks like this:

void GetSectionData(TCHAR name [], char **Address, DWORD * Size)

The function gets a name and returns the Address after it was allocated with *Size bytes. Here is an example of how to use the function in C:

char *addr[64]:
DWORD Size[64];
TCHAR name[260];
sprintf( name, "myDll.dll);
GetSectionAddress(name, &addr[index],&Size[index]);

I want to use this dll function in C# without unsafe.
My function Declaration should use the DllImport attribute but I dont know how to declare the parameters, mainly the Address and Size parameters (I assume that name can be declared as StringBuilder):

[DllImport("myDll.dll")]
public static extern void GetSectionData(?)

3 Answers 3

1

Generally, your pinvoke signature would be

static extern void GetSectionData(string name, out string address, out int size);

but:

  • at 'adress' parameter, you may need to indicate the relation to 'size' by [MarshalAs] attribute and proper SizeIndex value. If you change the 'out string' to 'out char[]' then surely it will be required, but if you use string and if your returned string is a normal null-terminated string, I think it will not be necessary
  • if the function allocates the memory for address array, you might encounter some problems as the usage of the function will assume that the caller must know how to free it.. please see i.e. https://stackoverflow.com/a/1932956/717732 or https://stackoverflow.com/a/12274007/717732 - the main problem is that there are really many ways to allocate the buffer (including stack-based temporary arrays..) and the caller will have hard time guessing. Especially the marshaller used in p/invoke, as it does not know anything about your code..
Sign up to request clarification or add additional context in comments.

Comments

0

According to Reflector, the way .Net Framework does this internally is to pass a StringBuilder instance into the char** parameter, while other (numeric) pointers are often passed in as IntPtr. A good example is FormatMessage, which has the following signature:

DWORD WINAPI FormatMessage(
  _In_      DWORD dwFlags,
  _In_opt_  LPCVOID lpSource,
  _In_      DWORD dwMessageId,
  _In_      DWORD dwLanguageId,
  _Out_     LPTSTR lpBuffer,
  _In_      DWORD nSize,
  _In_opt_  va_list *Arguments
);

is defined under Microsoft.Win32.SafeNativeMethods as

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr arguments);

System.ComponentModel.Win32Exception, which invokes this method, does

int error = 0; //Error code, for example
StringBuilder lpBuffer = new StringBuilder(0x100);
SafeNativeMethods.FormatMessage(0x3200, NativeMethods.NullHandleRef, error, 0, lpBuffer, lpBuffer.Capacity + 1, IntPtr.Zero)

If you want to extract the size parameter, you may define an unsafe method, and actually use the type int* for the size parameter.

Comments

0

[DllImport("myDll.dll")] public static extern void GetSectionData(StringBuilder name, ref IntPtr Address, ref int32 Size);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.