Interoperability in .NET

Creation QR in .NET Interoperability
7
Draw QR Code In .NET Framework
Using Barcode encoder for .NET framework Control to generate, create Denso QR Bar Code image in .NET applications.
Interoperability
QR-Code Reader In Visual Studio .NET
Using Barcode scanner for VS .NET Control to read, scan read, scan image in .NET applications.
0029f180 0029f190 0029f1a0 0029f1b0 0029f1c0 0029f1d0
Painting Barcode In Visual Studio .NET
Using Barcode printer for .NET Control to generate, create bar code image in .NET framework applications.
0029f200 0029f220 79f07fee 0029f240 00000000 00000001
Bar Code Recognizer In .NET
Using Barcode decoder for .NET Control to read, scan read, scan image in .NET framework applications.
79e7c6cc 00000000 0029f390 00000000 00000000 00000000
Make QR Code In Visual C#.NET
Using Barcode generator for .NET framework Control to generate, create QR Code ISO/IEC18004 image in VS .NET applications.
0029f250 0012c040 be1faf39 0029f390 00000000 79e7c1fa
Drawing QR Code ISO/IEC18004 In .NET
Using Barcode printer for ASP.NET Control to generate, create QR Code JIS X 0510 image in ASP.NET applications.
00000000 0029f1f0 0029f3dc 00448720 00000000 0029f19c
QR Code Generation In VB.NET
Using Barcode printer for .NET Control to generate, create Denso QR Bar Code image in .NET applications.
The first element looks like it may be a code address, so let s use the ln command to see if it resolves to anything:
Paint Code 128A In .NET
Using Barcode generation for Visual Studio .NET Control to generate, create Code128 image in VS .NET applications.
0:000> ln 79e73620 (79e73620) mscorwks!NDirectMethodFrameStandalone::'vftable' | (79e73688) mscorwks!NDirectMethodFrameSlim::'vftable' Exact matches: mscorwks!NDirectMethodFrameStandalone::'vftable' = <no type information>
Barcode Printer In Visual Studio .NET
Using Barcode creator for VS .NET Control to generate, create bar code image in VS .NET applications.
Sure enough, the output shows that the address corresponds to the virtual function table of the NDirectMethodFrameStandalone object We can further dump out the virtual function table and use the ln command on some of the function addresses to see what it contains:
EAN / UCC - 13 Printer In Visual Studio .NET
Using Barcode printer for .NET framework Control to generate, create EAN / UCC - 14 image in .NET framework applications.
0:000> dd 79e73620 l4 79e73620 79fc1a7d 79e730fc 7a0a3e0a 79e74034 0:000> ln 79fc1a7d Exact matches: mscorwks!DelegateTransitionFrame::GcScanRoots = <no type information> mscorwks!NDirectMethodFrame::GcScanRoots = <no type information>
Bar Code Generator In .NET
Using Barcode generation for VS .NET Control to generate, create barcode image in .NET applications.
Although the NDirectMethodFrame is largely undocumented, much information can be gleaned about the object by simply digging around the various functions that it contains The key to remember is that anytime you see an NDirectMethodFrame statement in the stack, you know that the code just transitioned from managed code into the native world So far, we ve seen a very simple example of a P/Invoke application and what the transition to native code looks like in the debugger The transition frame (as abstracted by the NDirectMethodFrame object) needs to be able to handle all sorts of different schemes depending on the complexity of the native function that is being called Perhaps the most critical of these schemes is the marshalling that takes place during the transition Marshalling simply refers to the conversion of various data representations that are not compatible in the two worlds (managed and native) For simple data
Drawing USS-93 In .NET
Using Barcode generator for .NET Control to generate, create Code 93 Full ASCII image in .NET applications.
Platform Invocation
Making Barcode In .NET Framework
Using Barcode maker for ASP.NET Control to generate, create barcode image in ASP.NET applications.
types such as an int or bool, the marshalling is for the most part automatic, but with other more complex data types, the CLR may need help from the caller to properly identify how the data should be marshaled Let s take a look at a slightly more complicated P/Invoke call as shown in Listing 7-2
EAN 13 Generation In VS .NET
Using Barcode creation for ASP.NET Control to generate, create EAN-13 Supplement 5 image in ASP.NET applications.
7 INTEROPERABILITY
Code 128A Generator In VB.NET
Using Barcode maker for .NET framework Control to generate, create ANSI/AIM Code 128 image in .NET framework applications.
Listing 7-2 P/Invoke example
Code 128 Code Set B Printer In Visual C#
Using Barcode creator for Visual Studio .NET Control to generate, create Code 128C image in .NET framework applications.
using using using using System; SystemText; SystemRuntimeInteropServices; SystemRuntimeRemoting;
Scanning Data Matrix 2d Barcode In Visual Studio .NET
Using Barcode recognizer for .NET framework Control to read, scan read, scan image in .NET applications.
namespace AdvancedNETDebugging7 { class PInvoke { private const int TableSize = 50; [StructLayout(LayoutKindSequential, CharSet = CharSetAnsi)] public class Node { public string First; public string Last; public string Social; public UInt32 Age; } [StructLayout(LayoutKindSequential)] public class Table { [MarshalAs(UnmanagedTypeByValArray, SizeConst = TableSize)] public IntPtr[] Nodes; public IntPtr Aux; } static void Main(string[] args) { PInvoke p = new PInvoke(); pRun(); }
Make Barcode In Java
Using Barcode drawer for Java Control to generate, create bar code image in Java applications.
(continues)
Drawing Barcode In Java
Using Barcode generation for Java Control to generate, create bar code image in Java applications.
7
Reading European Article Number 13 In .NET
Using Barcode recognizer for .NET Control to read, scan read, scan image in VS .NET applications.
Interoperability
Listing 7-2 P/Invoke example (continued)
public void Run() { Node[] nodes = new Node[TableSize]; nodes[0] = new Node(); nodes[0]First = "First Name 1"; nodes[0]Last = "Last Name 1"; nodes[0]Social = "Social 1"; nodes[0]Age = 30; nodes[1] = new Node(); nodes[1]First = "First Name 2"; nodes[1]Last = "Last Name 2"; nodes[1]Social = "Social 2"; nodes[1]Age = 31; nodes[2] = new Node(); nodes[2]First = "First Name 3"; nodes[2]Last = "Last Name 3"; nodes[2]Social = "Social 3"; nodes[2]Age = 32; Table t = new Table(); tAux = IntPtrZero; tNodes = new IntPtr[TableSize]; for (int i = 0; i < TableSize && nodes[i] != null; i++) { int nodeSize = MarshalSizeOf(typeof(Node)); tNodes[i] = MarshalAllocHGlobal(nodeSize); MarshalStructureToPtr(nodes[i], tNodes[i], false); } int tableSize = MarshalSizeOf(typeof(Table)); IntPtr pTable = MarshalAllocHGlobal(tableSize); MarshalStructureToPtr(t, pTable, false); Myfunc(pTable); } [DllImport("05Nativedll")] private static extern void Myfunc(IntPtr ptr); } }
Platform Invocation
The source code and binary for Listing 7-2 can be found in the following folders:
Source code: C:\ADND\7\PInvoke Binary: C:\ADNDBin\07PInvokeexe and 05Nativedll
7 INTEROPERABILITY
The source code in Listing 7-2 shows a slightly more complex P/Invoke call Rather than passing simple data types to the native function, it accepts a pointer to a Table structure that contains an array of the Node type The Node type in turn contains a set of basic types (string and int) Due to the complex nature of the data being passed from managed to native code, we can no longer rely on the standard marshaler; instead, we have to provide specific instructions on how the different elements of the complex type should be marshaled Those instructions come in the form of attributes applied at the type level or the member level For example, both the Node type and the Table type have the attribute StructLayout applied to them specifying the layout kind to be sequential (meaning all members are laid out sequentially in memory) Furthermore, the Nodes array in the Table type has the attribute MarshalAs applied to it specifying that the array should be treated as an array of value types In addition to annotating the different elements of the data structure being passed to native code, we also have to write explicit marshaling code that makes sure that we allocate the memory needed for the type as well as calling the MarshalStructureToPtr method that copies the elements from the data type to the newly allocated memory according to the marshaling annotations we added When all the preparation code has been put in place, we can finally make the actual call to the native method passing in the pointer to the newly created and marshaled Table type Although relying on the default marshaler is clearly far easier, there are times when custom (or explicit) marshaling is needed and writing explicit marshaling can be a daunting and error prone task The net effects of buggy marshaling code can range from immediate crashes to very subtle problems that do not surface right away; and knowing how to use the debugger to troubleshoot these problems is essential Let s start by using our example in Listing 7-2 as an illustration on how to do some basic debugging steps on properly written marshaling code Start by running 07Pinvokeexe under the debugger and set a breakpoint on the native function we are calling (Myfunc located in the 05Nativedll module)
0:000> bp 05native!MyFunc Bp expression '05native!MyFunc' could not be resolved, adding deferred bp 0:000> g ModLoad: 76730000 767f6000 C:\Windows\system32\ADVAPI32dll ModLoad: 761a0000 76263000 C:\Windows\system32\RPCRT4dll