不可或缺 Windows Native (1) - C 语言: hello c
不可或缺 Windows Native (1) - C 语言: hello c
作者:webabcd
介绍
不可或缺 Windows Native 之 C 语言
- 在 Windows Store Apps 中调用 C/C++
- hello 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
[源码下载]