2016-03-01 125 views
0

我想爲Pinvoke和本地調用做一個非常基本的Hello世界。
我創建2個項目(一個用於DLL和一個用於萬能的Windows應用程序) enter image description here你好世界Pinvoke和本地調用

所以我結束了一個項目heirachy這樣 enter image description here

有一個方法,在一個單一的解決方案我的DLL(文件NativeCalls.cpp):

#include "pch.h" 
#include "NativeCalls.h" 
#include <stdio.h> 

MYAPI void print_line(const char* str) { 
    printf("%s\n", str); 
} 

對事物的C#方,我有我NativeCalls.cs文件

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading.Tasks; 



namespace MSSurfaceHubMonitoring 
{ 

    public static class NativeCalls 
    { 

     [DllImport("NativeCalls.dll")] 
     private static extern void print_line(string str); 

     public static void sayHelo() 
     { 
      print_line("Hello, PInvoke!"); 
     } 
    } 
} 

在這一點上,我會構建並運行它,但得到一個錯誤,它無法找到DLL enter image description here

但是我相信它是依賴,而不是DLL它的自我。我已將dll的輸出目錄更改爲UW應用程序所在的根目錄(\ bin \ x86),因此它確實應該找到它。所以就像我說我認爲它的依賴關係,而不是實際的DLL。

以下是我在Dependency Walker中 enter image description here 看到,但我已經安裝了所有的C++封裝,我可以得到我的手,所以我不知道如何獲得缺少的依存關係。此外,這只是一個hello世界,爲什麼我需要所有這些庫。

FYI 我的dll項目沒有被UW應用引用。林不知道這需要或不?我不這麼認爲,因爲這是一個運行時的東西,所以只要dll在那裏,它應該找到它並閱讀它。但是,如果不管我嘗試添加到項目作爲參考,我得到這個錯誤: enter image description here

回答

0

我是找到這些方法聲明(即使不在類)

extern "C" { 
    __declspec(dllexport) int getPageSize() 
    { 
     SYSTEM_INFO siSysInfo; 
     GetSystemInfo(&siSysInfo); 
     return siSysInfo.dwPageSize; 
    } 
} 

extern "C" { 
    __declspec(dllexport) Windows::Foundation::Collections::IMap<Platform::String^, int> ^getSystemInfo() 
    { 
     SYSTEM_INFO siSysInfo; 
     GetSystemInfo(&siSysInfo); 

     IMap<String^, int> ^ret = 
      ref new Platform::Collections::Map<String^, int>; 
     ret->Insert("oemId", siSysInfo.dwOemId); 
     ret->Insert("cpuCount", siSysInfo.dwNumberOfProcessors); 
     ret->Insert("pageSize", siSysInfo.dwPageSize); 
     ret->Insert("processorType", siSysInfo.dwProcessorType); 
     ret->Insert("maxApplicationAddress", siSysInfo.lpMinimumApplicationAddress); 
     ret->Insert("minApplicationAddress", siSysInfo.lpMaximumApplicationAddress); 
     ret->Insert("activeProcessorMask", siSysInfo.dwActiveProcessorMask); 
     return ret; 
    } 

但最大的幫助最終我創造了我不需要的東西的包裝。在C#中,您可以直接調用本地方法,而不需要單獨的dll或組件項目。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading.Tasks; 


namespace Monitoring 
{ 

    public static class NativeCallsWrapper 
    { 
     private static SYSTEM_INFO sysInfo = new SYSTEM_INFO(); 
     private static MEMORYSTATUSEX mem = new MEMORYSTATUSEX(); 

     [DllImport("kernel32.dll", SetLastError = false)] 
     public static extern void GetSystemInfo([In, Out] SYSTEM_INFO Info); 

     [return: MarshalAs(UnmanagedType.Bool)] 
     [DllImport("kernel32.dll", SetLastError = true)] 
     static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); 

     static NativeCallsWrapper() 
     { 
      GetSystemInfo(sysInfo); 
      GlobalMemoryStatusEx(mem); 
     } 

     [StructLayout(LayoutKind.Explicit)] 
     public struct SYSTEM_INFO_UNION 

     { 

      [FieldOffset(0)] 
      public UInt32 OemId; 
      [FieldOffset(0)] 
      public UInt16 ProcessorArchitecture; 
      [FieldOffset(2)] 
      public UInt16 Reserved; 
     } 

     public struct SYSTEM_INFO 

     { 

      public SYSTEM_INFO_UNION CpuInfo; 
      public UInt32 PageSize; 
      public UInt32 MinimumApplicationAddress; 
      public UInt32 MaximumApplicationAddress; 
      public UInt32 ActiveProcessorMask; 
      public UInt32 NumberOfProcessors; 
      public UInt32 ProcessorType; 
      public UInt32 AllocationGranularity; 
      public UInt16 ProcessorLevel; 
      public UInt16 ProcessorRevision; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public class MEMORYSTATUSEX 
     { 
      public uint dwLength; 
      public uint dwMemoryLoad; 
      public ulong ullTotalPhys; 
      public ulong ullAvailPhys; 
      public ulong ullTotalPageFile; 
      public ulong ullAvailPageFile; 
      public ulong ullTotalVirtual; 
      public ulong ullAvailVirtual; 
      public ulong ullAvailExtendedVirtual; 
      public MEMORYSTATUSEX() 
      { 
       this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); 
      } 
     } 

     public static GeneralStatistics getGeneralStatistics() 
     { 
      GeneralStatistics generalStatistics = new GeneralStatistics(); 
      generalStatistics.numberOfProcesses = (int)sysInfo.NumberOfProcessors; 
      generalStatistics.memoryTotal = mem.ullTotalPhys/1048; 
      generalStatistics.memoryInUse = (mem.ullTotalPhys - mem.ullAvailPhys)/1048; 
      return generalStatistics; 
     } 
    } 
}