我跳了进去winnt.h,发现代码如下:
extern "C++" // templates cannot be declared to have 'C' linkage
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
Run Code Online (Sandbox Code Playgroud)
我想问一下如下问题:
extern "C++"工作怎么样?对于问题3,我的意思是我可以将模板的declearation和定义分开,然后为模板生成动态链接,而不使用这个技巧实际给出实现吗?
我正在创建一个非常简单的PInvoke示例:
extern "C" __declspec(dllexport) int Add(int a, int b)
{
return a + b;
}
[DllImport("CommonNativeLib.dll")]
extern public static int Add(int a, int b);
return NativeMethods.Add(a, b);
Run Code Online (Sandbox Code Playgroud)
但每当我调用上面的NativeMethods.Add方法时,我都会得到以下托管调试助手:
检测到PInvokeStackImbalance消息:对PInvoke函数'CommonManagedLib!CommonManagedLib.NativeMethods :: Add'的调用使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
然后调用以预期的返回值完成,但是出现MDA消息既令人讨厌又令人担忧 - 我还没有完全理解PInvoke,但是从我读过的内容我很确定我的签名是正确的 - 什么我做错了吗?
这都是在32位操作系统上.
在调试一些遗留代码时,我偶然发现令人惊讶的(对我而言)编译器行为.现在我想知道C++规范中的任何子句是否允许以下优化,其中函数调用对for-condition的副作用被忽略:
void bar()
{
extern int upper_bound;
upper_bound--;
}
void foo()
{
extern int upper_bound; // from some other translation unit, initially ~ 10
for (int i = 0; i < upper_bound; ) {
bar();
}
}
Run Code Online (Sandbox Code Playgroud)
在得到的解析中,存在一个控制路径,其中upper_bound保存在寄存器中,并且upper_boundin 的递减bar()永远不会生效.
我的编译器是Microsoft Visual C++ 11.00.60610.1.
老实说,我在N3242的 6.5.3和6.5.1中没有看到太多的摆动空间,但我想确定我没有错过任何明显的东西.
我有一个来自第三方的dll,它是用C++编写的.以下是来自dll文档的一些信息:
//start documentation
RECO_DATA{
wchar_t Surname[200];
wchar_t Firstname[200];
}
Run Code Online (Sandbox Code Playgroud)
描述:用于接收功能结果的数据结构.所有功能结果将存储为Unicode(UTF-8).
方法:
bool recoCHN_P_Name(char *imgPath,RECO_DATA *o_data);
Run Code Online (Sandbox Code Playgroud)
输入:
char * imgPath
Run Code Online (Sandbox Code Playgroud)
此功能识别的图像位置的完整路径
RECO_DATA * o_data
Run Code Online (Sandbox Code Playgroud)
用于接收功能结果的数据对象.函数返回:如果成功则返回true,否则返回false.
//end documentation
Run Code Online (Sandbox Code Playgroud)
我试图从我的C#应用程序调用recoCHN_P_Name.为此,我想出了这段代码:
导入dll的代码:
public class cnOCRsdk
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct RECO_DATA{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=200)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]
public string Surname;
}
[DllImport(@"cnOCRsdk.dll", EntryPoint="recoCHN_P_Name")]
public static extern bool recoCHN_P_Name(byte[] imgPath, RECO_DATA o_data);
}
Run Code Online (Sandbox Code Playgroud)
调用函数的代码:
cnOCRsdk.RECO_DATA recoData = new cnOCRsdk.RECO_DATA();
string path = @"C:\WINDOWS\twain_32\twainrgb.bmp";
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytes …Run Code Online (Sandbox Code Playgroud) 这是一个新手C/Objective-C问题:-)
假设我想要一个CGRectOne和一个CGRectTwo常量.
我该怎么说呢?
谢谢,Jérémy
那么,阅读"有点旧"的书("C编程语言",第二版,丹尼斯·里奇),我得到了以下几点:
外部变量必须在任何函数之外定义一次; 这为它预留了存储空间.该变量还必须在每个想要访问它的函数中声明
我就像 - 什么?!
"还必须在每个想要访问它的函数中声明变量".然后,我又一次感到震惊:
int max;
/* ... */
int main()
{
extern int max;
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
还有一个 - 什么?!
据我所知(显然,它并不多,而且远远不够),extern只有当你在某个地方定义一个全局变量而你想通过另一个文件访问它时才有意义(而不是再次定义它).
所以:
extern int max 内的main或任何其他功能?文件1.c.
int a[10];
Run Code Online (Sandbox Code Playgroud)
文件main.c:
extern int *a;
int main()
{
printf("%d\n", a[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给我一个段错误!出了什么问题?
我一直在我的头文件中使用静态const,如下所示:
static NSString * const myString = @"foo";
Run Code Online (Sandbox Code Playgroud)
但是已经读过这不是"安全"或正确的方法.显然,如果我想从另一个类访问我的const字符串,我应该在我的.h中声明字符串:
extern NSString * const myString;
Run Code Online (Sandbox Code Playgroud)
然后在我的.m文件中:
NSString * const myString = @"foo";
Run Code Online (Sandbox Code Playgroud)
它是否正确?如果是这样,是什么原因不直接在我的.h文件中将其声明为静态?它工作得很好,我看不到任何"安全"问题.它是一个const,因此它不能从外部改变,而是我故意需要在类之外访问它.我能想到的另一件事就是隐藏字符串的值?
我已经看到了两种创建全局变量的方法,有什么区别,你什么时候使用它们?
//.h
extern NSString * const MyConstant;
//.m
NSString * const MyConstant = @"MyConstant";
Run Code Online (Sandbox Code Playgroud)
和
//.h
extern NSString *MyConstant;
//.m
NSString *MyConstant = @"MyConstant";
Run Code Online (Sandbox Code Playgroud) 我经常遇到包含extern "C"警卫的C头文件,
但不包含任何实际功能.例如:
/* b_ptrdiff.h - base type ptrdiff_t definition header */
#ifndef __INCb_ptrdiff_th
#define __INCb_ptrdiff_th
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef long ptrdiff_t;
#endif /* _PTRDIFF_T */
#ifdef __cplusplus
}
#endif
#endif /* __INCb_ptrdiff_th */
Run Code Online (Sandbox Code Playgroud)
我知道这extern "C"可以防止对函数进行名称修改,但它是否也可以防止变量和类型声明的其他接口问题?
extern "C"在产生兼容性方面,上述示例中的使用是否毫无意义?