根据微软官方文档总结的,原文都是英文,理解有误望指正!
1.使用C++/CX
2.使用WRL + C++
The Visual C++ component extensions (C++/CX) supports user-defined reference classes and structs, and user-defined value classes and structs. Public forms of these types can be passed between Windows Runtime components and apps, whereas standard C++ classes and structs cannot.
You can freely mix standard C++ types and functions in a ref class. However, between Windows Runtime components, you can pass only public ref classes, ref structs, value structs, and value classes.
Reference types are implemented as reference-counted pointers to Windows Runtime objects. C++/CX automatically modifies the reference count (ref count) of an object when it is instantiated, copied, set to null, or goes out of scope. When the reference count becomes zero, the object’s destructor is immediately invoked just as in any C++ program. There is no separate garbage collection mechanism in C++/CX
You typically use these extensions in the public interfaces where your code is passing Windows Runtime types back and forth across the ABI to JavaScript, C#, or Visual Basic (or even another C++ module). Visual C++ provides a variety of implicit conversions between Windows Runtime types and standard C++ types. The typical pattern is to use standard C++ types and libraries internally as usual, and convert to Windows Runtime types in the public interfaces.
Only Windows Runtime types can be passed across the ABI boundary. The compiler will raise an error if the component has a type such as std::wstring as a return type or parameter in a public method. If you use the C++ built-in types such as int, double, and so on, the compiler automatically converts them to the appropriate Windows Runtime type—int32, float64, and so on—in parameters and return types of public methods. No such conversion occurs unless you are passing the type across the ABI.For more information, see Visual C++ language reference.
An activatable class (also known as a ref class) is one that can be instantiated from another language such as JavaScript. To be consumable from another language such as JavaScript, a component must contain at least one activatable class. An activatable class must inherit directly from Platform::Object. For more information, see Type System (C++/CX).
An activatable class must be declared as public ref class sealed. The ref class keywords tell the compiler to create the class as a Windows Runtime compatible type, and the sealed keyword specifies that the class cannot be inherited. A class must be sealed to be consumed by JavaScript.
C++
// Implicit conversion of return value to equivalent Windows Runtime type.
double LogCalc(double input)
{
// Use C++ standard library as usual.
return std::log(input);
}
JavaScript
//Call a method
var num = nativeObject.logCalc(21.5);
document.getElementById('callmethod').innerHTML = num;
C++
// Custom struct
public value struct Batter
{
String^ Name;
int Number;
double BattingAverage;
};
Public ref class LangSample
{
private:
MyData batter_;
public:
property Batter
{
Batter get(){ return batter_; }
}
}
JavaScript
var myData = nativeObject.batter;
document.getElementById('myDataResult').innerHTML = myData.name + " , " + myData.number + " , " + myData.battingAverage.toPrecision(3);
A delegate is a Windows Runtime type that represents a function object. You can use delegates in connection with events, callbacks, and asynchronous method calls to specify an action to be performed later. Like a function object, the delegate provides type-safety by enabling the compiler to verify the return type and parameter types of the function. The declaration of a delegate resembles a function signature, the implementation resembles a class definition, and the invocation resembles a function invocation. A delegate instance can also be created "inline" by using a lambda expression.
C++
namespace mycomp
{
public delegate void PropertyChangedHandler(Object^ source, int i);
public ref class sealed LangSample
{
event PropertyChangedHandler^ propertyChangedEvent;
// Property that has custom setter/getter
property int PropertyA
{
int get() { return _propertyAValue; }
void set(int propertyAValue)
{
if (propertyAValue != _propertyAValue)
{
_propertyAValue = propertyAValue;
propertyChangedEvent(this, propertyAValue);
}
}
}
};
}
JavaScript
// Define an event handler method
var singlecasthandler = function (ev) {
document.getElementById('singlecastresult').innerHTML = ev;
};
// Subscribe to the event
nativeObject.onpropertychangedevent = singlecasthandler;
// Set the value of the property and fire the event
nativeObject.propertyA = 2 * propValue;