Note that there are some explanatory texts on larger screens.

plurals
  1. POMarshalling from C# to a DLL with a TCHAR** x[] parameter
    primarykey
    data
    text
    <p>I am trying to call a Win32 DLL from some C#. The DLL function is declared as follows:</p> <pre class="lang-c prettyprint-override"><code>extern "C" __declspec(dllexport) UINT foo(TCHAR** list[], int&amp; listSize, TCHAR* error); </code></pre> <p>In C#, I declare the external function like so:</p> <pre class="lang-cs prettyprint-override"><code>[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] static extern uint foo(StringBuilder[] list, ref int listSize, StringBuilder error); </code></pre> <p>My problem has to do with the <em>list</em> parameter, which is an array of StringBuilder classes.</p> <p>Some test code where I call the DLL function is as follows: (Note: I realise that there are boundary checks missing, etc. At this stage, I am just trying to get things working).</p> <pre class="lang-cs prettyprint-override"><code>// allocate a buffer for a possible error message being returned StringBuilder error = new StringBuilder(1000); // allocate buffers for the list of strings returned StringBuilder[] list = new StringBuilder[10]; for (int i = 0; i &lt; 10; i++) { list[i] = new StringBuilder(1000); } int listSize = list.Length; uint result = foo(list, ref listSize, error); </code></pre> <p>Passing the StringBuilder as a buffer for the <em>error</em> parameter, works fine. I can set its contents in the DLL as follows:</p> <pre class="lang-cpp prettyprint-override"><code>_tcscpy(error, _T("Something went wrong"); </code></pre> <p>When the C# call to <em>foo</em> returns, the <em>string error</em> variable has the text we set it to in the DLL.</p> <p>But, I cannot work out how to marshal the <em>StringBuilder[] list</em> parameter.</p> <p>In the C++, I am able to set the contents of the <em>list</em> array:</p> <pre class="lang-cpp prettyprint-override"><code>_tcscpy((*list)[0], _T("First item")); // and so on... </code></pre> <p>And, even though there is no crash that occurrs due to any possible problematic marshalling, the <em>list</em> in the C#, when the call to <em>foo()</em> returns, does not contain any of the strings we set in the C++.</p> <p>I'm guessing that the problem is with the <em>DllImport</em> and how I've declared the <em>list</em> parameter should be marshalled.</p> <p>By the way, the example DLL has a matching function which one would then call to deallocate the "TCHAR** list" returned by the example <em>foo</em> shown above. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload