做人呢就要有始有终不是么。。我还是把这个翻译完了事。
Coding with C++
With the C++ project finally set up, it‘s time to start adding some code. We‘ll start with the NativeAdd.h file so open up that file and enter the code below.
C++项目设置完后,添加以下的代码,以NativeAdd.h开始,如下
#include "FlashRuntimeExtensions.h" extern "C" { __declspec(dllexport) void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet); __declspec(dllexport) void ExtFinalizer(void* extData); __declspec(dllexport) FREObject doAdd(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]); }
As mentioned, I‘m no authority on C++, but I‘ll do my best to explain the code above. First, the #include is comparable to the import statement in ActionScript. This tells the file to also use the FlashRuntimeExtensions.h file. The extern "C" line tells the compiler that we want the following block of code to be compiled C-style and not C++ style.
作者:我C++很渣,我尽力解释一下代码,首先,#include 转化为Import 语句到As3,这个告诉文件,使用FlashRuntimeExtensions.h头文件, extern "C" 告诉编译器,我们希望把下面括起来的代码用C语法编译。
The command I‘m least familiar with is the __declspec(dllexport) but I think it is safe to assume this essentially marks the following functions as exports from our dll; meaning they are visible to other applications that might use the dll.
作者说 __declspec(dllexport)他不熟,他只能猜测一下其作用。
Following the __declspec(dllexport), we define our function signatures. Unlike AS3, the return type comes first. It is followed by the function name and then the parameter list. The first two functions are for setting up and shutting down our Native Extension. The third function is the one that will handle the bulk of the work for us, doAdd. Note that in this header file, we are simply defining the function signatures, but not providing a function body. We will do that next in the NativeAdd.cpp file.
解释一下,C语法和AS3语法的区别。重点是,前两个方法,第一个启用,第二个关闭 Native Extension,第三个是拿来处理 doAdd方法的。下文详细讲
Open the NativeAdd.cpp file and enter the following functions. We‘ll go over each function one at a time, but first let‘s just make sure the file is all ready to go. At this point, make sure the file contains only the following code.
打开NativeAdd.cpp 添加以下方法,此时需要确保,里面只有以下内容。
#include "NativeAdd.h" #include <stdlib.h> extern "C" { }
We‘re going to be adding all of our functions inside the extern "C" block and we‘ll start with our doAdd function.
我们会把所有的方法,放在 extern "C" 的括号里,首先是doAdd
FREObject doAdd(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { int32_t one, two, sum; FREObject result; FREGetObjectAsInt32(argv[0], &one); FREGetObjectAsInt32(argv[1], &two); sum = one + two; FRENewObjectFromInt32(sum, &result); return result; }
This is the function that is actually going to do the work for our extension and return our sum. To begin with, we declare a few variables of type int32_t. The next variable is an FREObject that will hold the result of our addition. The FRE types are how data is passed between Flash and C; I highly suggest checking out the Adobe documentation on working with the various types if you are going to be doing more of this on your own.
这个就是加法方法的主题,(代码自己看),FREObject 拿来保存结果,FREtypes 就是数据从Flash到C之间传输的类型。作者很建议看一下Adobe documentation 关于多种类型的用法,然后大家可以做更多。
The next two function calls grab the data passed in by Flash, which comes in via the argv array, and stores it in our locally defined variables one and two. These represent the two numbers that will be added together. Next we do the actual addition and store the result in the sum variable. The last thing we need to do before returning the sum is to convert it into an FRE object that Flash can understand. The function FRENewObjectFromInt32 takes care of that for us and now we can return the result.
FREGetObjectAsInt32 这个方法用于从argv 里面获取Flash的数据,就是两个加数,然后保存到本地的两个变量里。然后做个加法。最后,用FRENewObjectFromInt32 方法把本地C中所加的结果返回Flash。
You may be wondering about the ampersands and asterisks if you aren‘t familiar with C coding. It has to do with the actual memory address of the variables and is quite beyond the scope of this tutorial, but if you‘re interested in learning more, you can read up on pointers on wikipedia.
你估计会好奇是怎么用C语言做到的,这个主要是用内存地址之类的,超出本教程范围不再讨论。如果你感兴趣,先去看看指针部分。
The next couple of functions we define are not specified in our NativeAdd.h file, but they are necessary all the same.
下面两个方法没有在头文件定义,但是一样要用。
void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctions, const FRENamedFunction** functions) { *numFunctions = 1; FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*(*numFunctions)); func[0].name = (const uint8_t*)"doAdd"; func[0].functionData = NULL; func[0].function = &doAdd; *functions = func; } void ContextFinalizer(FREContext ctx) { return; }
These methods deal with the ActionScript ExtensionContext object which we‘ll see when we get to the AS part of this tutorial. The first function is the initializer. First we tell it how many functions we will define, which in this case is just the 1, doAdd. Next we allocate memory for the function using malloc. After that we fill in some data regarding our function. We give it a name, set the data to NULL and then mark the address of our function. Lastly, we assign our FRENamedFunction pointer, func, to the passed in double-pointer functions. I don‘t have a good grasp on working with pointers so most of this I got from the Adobe docs.
这些方法,处理As3 ExtensionContext object, 等到后面我们涉及到As3部分就会讲到。第一个方法是初始化,告诉有几个方法定义了,我们的情况是只有一个,doAdd,然后分配内存用Malloc 。 之后,输入一些数据给方法,比如name 之类。
设置Data为Null ,标记方法低值,最后 分派一个FRENamedFunction 指针,指向指针的指针。作者说老子不会这玩意,完全抄的Adobe docs。。。(指向指针的指针。就是分配一个地址,这个地址指向一个指针的内存地址。个人理解)
The other function, the finalizer, doesn‘t really need to do anything so we keep it simple with nothing more than an empty return statement.
The last two functions we need to add are the ones we had declared in our .h file; the ExtInitializer and ExtFinalizer functions. The functions we covered above are responsible for dealing with the extension context object, while the ones below are for the actual extension itself.
另外一个方法,finalizer 没什么特别的,下面两个方法,ExtInitializer and ExtFinalizer functions .
void ExtInitializer(void** extData, FREContextInitializer* ctxInitializer, FREContextFinalizer* ctxFinalizer) { *ctxInitializer = &ContextInitializer; *ctxFinalizer = &ContextFinalizer; } void ExtFinalizer(void* extData) { return; }
Again, the finalizer here is simple so we‘ll focus on the ExtInitializer function. This function is actually pretty simple as well. All we‘re doing is telling the extension where to find the context initializer and finalizer functions - that‘s it.
Your NativeAdd.cpp file should look like this when it is completed.
方法很简单,告诉,extension 去哪里找 initializer ,finalizer 的内容。完了。
下面是完整版
// NativeAdd.cpp : Defines the exported functions for the DLL application. #include "NativeAdd.h" #include <stdlib.h> extern "C" { FREObject doAdd(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { int32_t one, two, sum; FREObject result; FREGetObjectAsInt32(argv[0], &one); FREGetObjectAsInt32(argv[1], &two); sum = one + two; FRENewObjectFromInt32(sum, &result); return result; } void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctions, const FRENamedFunction** functions) { *numFunctions = 1; FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*(*numFunctions)); func[0].name = (const uint8_t*)"doAdd"; func[0].functionData = NULL; func[0].function = &doAdd; *functions = func; } void ContextFinalizer(FREContext ctx) { return; } void ExtInitializer(void** extData, FREContextInitializer* ctxInitializer, FREContextFinalizer* ctxFinalizer) { *ctxInitializer = &ContextInitializer; *ctxFinalizer = &ContextFinalizer; } void ExtFinalizer(void* extData) { return; } } </stdlib.h>
You should now be able to successfully build the dll! You can find the NativeAdd.dll in either the debug or release folder in your project directory.
很好,成功编译一下,你就可以在Debug或者Release文件下找到NativeAdd.dLL文件!