PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Visual Studio 2008/CSPInvokeDll/Program.cs

#
C# | 159 lines | 58 code | 26 blank | 75 comment | 2 complexity | 67c02e7decc5d28c58043f7724d8825a MD5 | raw file
  1. /****************************** Module Header ******************************\
  2. * Module Name: Program.cs
  3. * Project: CSPInvokeDll
  4. * Copyright (c) Microsoft Corporation.
  5. *
  6. * Platform Invocation Services (P/Invoke) in .NET allows managed code to call
  7. * unmanaged functions that are implemented and exported in unmanaged DLLs.
  8. * This VC# code sample demonstrates using P/Invoke to call the functions
  9. * exported by the native DLLs: CppDynamicLinkLibrary.dll, user32.dll and
  10. * msvcrt.dll.
  11. *
  12. * This source is subject to the Microsoft Public License.
  13. * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
  14. * All other rights reserved.
  15. *
  16. * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  17. * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  19. \***************************************************************************/
  20. #region Using directives
  21. using System;
  22. using System.Runtime.InteropServices;
  23. #endregion
  24. namespace CSPInvokeDll
  25. {
  26. class Program
  27. {
  28. static void Main(string[] args)
  29. {
  30. bool isLoaded = false;
  31. const string moduleName = "CppDynamicLinkLibrary";
  32. // Check whether or not the module is loaded.
  33. isLoaded = IsModuleLoaded(moduleName);
  34. Console.WriteLine("Module \"{0}\" is {1}loaded", moduleName,
  35. isLoaded ? "" : "not ");
  36. //
  37. // Access the global data exported from the module.
  38. //
  39. // P/Invoke does not allow you to access the global data exported
  40. // from a DLL module.
  41. //
  42. // Call the functions exported from the module.
  43. //
  44. string str = "HelloWorld";
  45. int length;
  46. length = NativeMethod.GetStringLength1(str);
  47. Console.WriteLine("GetStringLength1(\"{0}\") => {1}", str, length);
  48. length = NativeMethod.GetStringLength2(str);
  49. Console.WriteLine("GetStringLength2(\"{0}\") => {1}", str, length);
  50. // P/Invoke the stdcall API, MessageBox, in user32.dll.
  51. MessageBoxResult msgResult = NativeMethod.MessageBox(
  52. IntPtr.Zero, "Do you want to ...", "CSPInvokeDll",
  53. MessageBoxOptions.OkCancel);
  54. Console.WriteLine("user32!MessageBox => {0}", msgResult);
  55. // P/Invoke the cdecl API, printf, in msvcrt.dll.
  56. Console.Write("msvcrt!printf => ");
  57. NativeMethod.printf("%s!%s\n", "msvcrt", "printf");
  58. //
  59. // Call the callback functions exported from the module.
  60. //
  61. // P/Invoke a method that requires callback as one of the args.
  62. CompareCallback cmpFunc = new CompareCallback(CompareInts);
  63. int max = NativeMethod.Max(2, 3, cmpFunc);
  64. // Make sure the lifetime of the delegate instance covers the
  65. // lifetime of the unmanaged code; otherwise, the delegate
  66. // will not be available after it is garbage-collected, and you
  67. // may get the Access Violation or Illegal Instruction error.
  68. GC.KeepAlive(cmpFunc);
  69. Console.WriteLine("Max(2, 3) => {0}", max);
  70. //
  71. // Use the class exported from the module.
  72. //
  73. // There is no easy way to call the classes in a native C++ DLL
  74. // module through P/Invoke. Visual C++ Team Blog introduced a
  75. // solution, but it is complicated:
  76. // http://go.microsoft.com/?linkid=9729423.
  77. // The recommended way of calling native C++ class from .NET are
  78. // 1) use a C++/CLI class library to wrap the native C++ module,
  79. // and your .NET code class the C++/CLI wrapper class to
  80. // indirectly access the native C++ class.
  81. // 2) convert the native C++ module to be a COM server and expose
  82. // the native C++ class through a COM interface. Then, the
  83. // .NET code can access the class through .NET-COM interop.
  84. // Unload the DLL by calling GetModuleHandle and FreeLibrary.
  85. if (!FreeLibrary(GetModuleHandle(moduleName)))
  86. {
  87. Console.WriteLine("FreeLibrary failed w/err {0}",
  88. Marshal.GetLastWin32Error());
  89. }
  90. // Check whether or not the module is loaded.
  91. isLoaded = IsModuleLoaded(moduleName);
  92. Console.WriteLine("Module \"{0}\" is {1}loaded", moduleName,
  93. isLoaded ? "" : "not ");
  94. }
  95. /// <summary>
  96. /// This is the callback function for the method Max exported from
  97. /// the DLL CppDynamicLinkLibrary.dll.
  98. /// </summary>
  99. /// <param name="a">the first integer</param>
  100. /// <param name="b">the second integer</param>
  101. /// <returns>
  102. /// The function returns a positive number if a > b, returns 0 if a
  103. /// equals b, and returns a negative number if a &lt b.
  104. /// </returns>
  105. static int CompareInts(int a, int b)
  106. {
  107. return (a - b);
  108. }
  109. #region Module Related Operations
  110. /// <summary>
  111. /// Check whether or not the specified module is loaded in the
  112. /// current process.
  113. /// </summary>
  114. /// <param name="moduleName">the module name</param>
  115. /// <returns>
  116. /// The function returns true if the specified module is loaded in
  117. /// the current process. If the module is not loaded, the function
  118. /// returns false.
  119. /// </returns>
  120. static bool IsModuleLoaded(string moduleName)
  121. {
  122. // Get the module in the process according to the module name.
  123. IntPtr hMod = GetModuleHandle(moduleName);
  124. return (hMod != IntPtr.Zero);
  125. }
  126. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  127. static extern IntPtr GetModuleHandle(string moduleName);
  128. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  129. [return: MarshalAs(UnmanagedType.Bool)]
  130. static extern bool FreeLibrary(IntPtr hModule);
  131. #endregion
  132. }
  133. }