Note that there are some explanatory texts on larger screens.

plurals
  1. POCall unmanaged Code from C# - returning a struct with arrays
    primarykey
    data
    text
    <p>[EDIT] I changed the source as suggested by Stephen Martin (highlighted in bold). And added the C++ source code as well.</p> <p>I'd like to call an unmanaged function in a self-written C++ dll. This library reads the machine's shared memory for status information of a third party software. Since there are a couple of values, I'd like to return the values in a struct. However, within the struct there are <code>char []</code> (Arrays of char with a fixed size). I now try to receive that struct from the dll call like this:</p> <pre><code>[StructLayout(LayoutKind.Sequential)] public struct SYSTEM_OUTPUT { UInt16 ReadyForConnect; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] String VersionStr; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] String NameOfFile; // actually more of those } public partial class Form1 : Form { public SYSTEM_OUTPUT output; [DllImport("testeshm.dll", EntryPoint="getStatus")] public extern static int getStatus(out SYSTEM_OUTPUT output); public Form1() { InitializeComponent(); } private void ReadSharedMem_Click(object sender, EventArgs e) { try { label1.Text = getStatus(out output).ToString(); } catch (AccessViolationException ave) { label1.Text = ave.Message; } } } </code></pre> <p>I will post code from the c++ dll as well, I'm sure there's more to hunt down. The original struct <code>STATUS_DATA</code> has an array of four instances of the struct <code>SYSTEM_CHARACTERISTICS</code> and within that struct there are <code>char[]</code>s, that are not being filled (yet), resulting in a bad pointer. That's why I'm trying to extract a subset of the first <code>SYSTEM_CHARACTERISTICS</code> item in <code>STATUS_DATA</code>.</p> <pre><code>#include &lt;windows.h&gt; #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;tchar.h&gt; #include &lt;iostream&gt; #if defined(_MSC_VER) #include &lt;windows.h&gt; #define DLL extern "C" __declspec(dllexport) #else #define DLL #endif using namespace std; enum { SYSID_LEN = 1024, VERS_LEN = 128, SCENE_LEN = 1024 }; enum { MAX_ENGINES = 4 }; struct SYSTEM_CHARACTERISTICS { unsigned short ReadyForConnect; char VizVersionStr[VERS_LEN]; char NameOfFile[SCENE_LEN]; char Unimplemented[SCENE_LEN]; // not implemented yet, resulting to bad pointer, which I want to exclude (reason to have SYSTEM_OUTPUT) }; struct SYSTEM_OUTPUT { unsigned short ReadyForConnect; char VizVersionStr[VERS_LEN]; char NameOfFile[SCENE_LEN]; }; struct STATUS_DATA { SYSTEM_CHARACTERISTICS engine[MAX_ENGINES]; }; TCHAR szName[]=TEXT("E_STATUS"); DLL int getStatus(SYSTEM_OUTPUT* output) { HANDLE hMapFile; STATUS_DATA* pBuf; hMapFile = OpenFileMapping( FILE_MAP_READ, // read access FALSE, // do not inherit the name szName); // name of mapping object if (hMapFile == NULL) { _tprintf(TEXT("Could not open file mapping object (%d).\n"), GetLastError()); return -2; } pBuf = (STATUS_DATA*) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); if (pBuf == NULL) { _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError()); CloseHandle(hMapFile); return -1; } output-&gt;ReadyForConnect = pBuf-&gt;engine[0].ReadyForConnect; memcpy(output-&gt;VizVersionStr, pBuf-&gt;engine[0].VizVersionStr, sizeof(pBuf-&gt;engine[0].VizVersionStr)); memcpy(output-&gt;NameOfFile, pBuf-&gt;engine[0].NameOfFile, sizeof(pBuf-&gt;engine[0].NameOfFile)); CloseHandle(hMapFile); UnmapViewOfFile(pBuf); return 0; } </code></pre> <p>Now I'm getting an empty <code>output</code> struct and the return value ist not 0 as intended. It is rather a changing number with seven digits, which leaves me puzzled... Have I messed up in the dll? If I make the unmanaged code executable and debug it, I can see, that <code>output</code> is being filled with the appropriate values.</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.
    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