Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Issues I see:</p> <ol> <li><p><code>InitDotNet</code> takes long instead of <code>CB_func1</code> and <code>CB_func2</code>. This is a two-fold problem for 64-bit versions of your program: it leads to an exported name mismatch for stdcall functions and, worse, it can cause pointer truncation if <code>InitDotNet</code> somehow manages to get called.</p></li> <li><p>InitDotNet is not marked <code>__stdcall</code>. The default calling convention is cdecl. The cdecl naming convention is "prefix with underscore", so the exported name is "_InitDotNet". However, the stdcall naming convention is "prefix with underscore, postfix with @ followed by the size of the arguments, in bytes", so the expected exported name would be "_InitDotNet@8" (with the current signature of taking two longs). You should use a program like dumpbin or <a href="http://www.dependencywalker.com/" rel="nofollow">depends.exe</a> to view the names of the functions exported by your DLL. <strong>This mismatch is likely the reason the runtime can't find <code>InitDotNet</code>, assuming 32-bit Windows</strong>. You should not be specifying <code>EntryPoint</code> to the <code>DllImport</code> attribute if this is corrected (the runtime will figure out the appropriate name automatically). </p></li> <li><p>As pointed out by cdhowie in the comments, you need to keep the two delegates you're passing to the native code "alive". The .NET garbage collector is incapable of knowing that the function pointers are being stored by the native code. To prevent the garbage collector from collecting them, keep a reference to the delegates around (such as in a field for an object that is guaranteed to outlive the native code's use for them) or use a <code>GCHandle</code>. Note if you use a <code>GCHandle</code>: you do not need to use a pinned handle; the function pointer that is actually passed to your code is a stub and the stub remains in the same place even if the delegate is moved by the garbage collector. However, the stub is deleted when the delegate is collected, so it is vital to ensure the delegate does not get collected until the native code no longer needs the callbacks.</p></li> </ol>
 

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