[源碼下載]
作者:webabcd
介紹
不可或缺 Windows Native 之 C 語言
示例
1、演示如何在 Windows Store Apps(C#) 中調用 C/C++,需要新建 Windows Runtime Component(C++) 項目
NativeDll/Simple.h
/* * .h 頭文件 */ // 保證頭文件只被編譯一次(即使被多次引用,也只被編譯一次) #pragma once namespace NativeDll // 命名空間 { public ref class Simple sealed // 類 { public: int Add(int x, int y); // 方法 }; }
NativeDll/Simple.cpp
/* * .cpp 實現文件 * * 為了支持 Windows Runtime Component 這種方式,所以引入 Microsoft created the Visual C++ component extensions (C++/CX),可以將其看作是連接“調用者”和“C/C++”之間的橋梁,元數據是 windows metadata (.winmd) files * 為了讓“調用者”調用 Windows Runtime Component,所以 C++/CX 會有自己的一些數據類型,比如字符串是 Platform::String^ 類型的,這樣才能讓“調用者”調用 * 關於 C++/CX 的相關知識請參見:https://msdn.microsoft.com/en-us/library/hh755822.aspx */ #include "pch.h" // 預編譯頭文件 #include "Simple.h" // 需要實現的頭文件 // 頭文件中定義的命名空間 using namespace NativeDll; // 實現頭文件中的方法 int Simple::Add(int x, int y) { return x + y; }
NativeDemo/Simple.xaml.cs
/* * 演示如何用 C# 調用 C++ * * 對應的 Windows Runtime Component(C++) 詳見 NativeDll 項目 * 注意:Windows Runtime Component 項目會生成 .winmd 文件,winmd - Windows Metadata,其是語言無關的 */ using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace NativeDemo.Demo { public sealed partial class Simple : Page { public Simple() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { // 調用 C++ 中的函數 NativeDll.Simple simple = new NativeDll.Simple(); int result = simple.Add(1, 1); lblMsg.Text = "1 + 1 = " + result.ToString(); } } }
readme.txt
1、為了使用 C 語言,需要選中相應的 .c 文件 -> 右鍵 -> 屬性 -> c/c++ -> 高級 -> 編譯為 -> 編譯為 C++ 代碼(/TP) 2、比如你要用 strcpy 的話,在 vs 中會警告你,要求你用 strcpy_s,但是 strcpy_s 是微軟自己的,為了去掉這個警告可以這麼做: a) 在文件開頭定義 #define _CRT_SECURE_NO_WARNINGS b) 或者一勞永逸的方法:dll 項目 -> 右鍵 -> 屬性 -> c/c++ -> 預處理器 -> 在“預處理器定義”增加 “_CRT_SECURE_NO_WARNINGS” 3、調試本地代碼:選中解決方案 -> 右鍵 -> 屬性 -> 調試 -> 調試器類型 -> 選中“混合(托管和本機)” 4、如何在新建 c 代碼時,默認保存為 utf-8 格式:在類似 D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcprojectitems 的目錄下修改模板文件“hfile.h”和“newc++file.cpp”的文件格式為 utf-8
2、hello c
cHello.h
// c 的 .h 文件 // 頭文件一般用於放置:需要向外暴露的宏定義,全局變量聲明,函數聲明 // 防止同一文件的二次編譯。比如你有兩個 c 文件,這兩個 c 文件都 include 了同一個頭文件,在編譯時,這兩個 c 文件就會被一同編譯,那麼就帶來了聲明沖突的問題 #ifndef _MYHEAD_HELLO_ // 是 if not defined 的縮寫,如果沒定義 _MYHEAD_HELLO_ 則執行這一塊 #define _MYHEAD_HELLO_ // 定義 _MYHEAD_HELLO_ // 在 c++ 中寫 c 語言代碼 #ifdef __cplusplus // 如果當前是 c++ 環境 extern "C" // 告訴 c++ 下面的 { } 塊中寫的是 c 語言代碼 { #endif // 函數聲明 char *demo_cHello(char *name); #ifdef __cplusplus // 如果當前是 c++ 環境 } #endif /* // 在 windows 環境下,可以簡寫成這樣 #ifdef __cplusplus extern "C" #endif char *demo_cHello(char *name); */ #endif // #ifndef _MYHEAD_HELLO_
cHello.c
/* * hello c */ #include "pch.h" // 預編譯頭文件 #include "cHello.h" // 引入需要實現的頭文件 #include "cHelper.h" // 引入自定義函數的頭文件 char *demo_cHello(char *name) { return str_concat2("hello: ", name); } // 本 demo 無法演示 main 函數,所以以下做一些關於 main 函數的文字說明 // main 函數是入口函數,不能被其它函數調用 // 假設命令為:可執行文件名 參數1 參數2 參數3 int main(int argc, char *argv[]) // main 函數也可以是無參無返回值的,即:int main(void) { } 或 void main(void) { } 都是可以的 { // argc 是參數個數;argv 是參數值 // argc - 等於 4 (注:“可執行文件名”也算一個參數) // argv[0] - 可執行文件名; argv[1] - 參數1; argv[2] - 參數2; argv[3] - 參數3 // 返回 0 代表正常 return 0; }
OK
[源碼下載]