I have one method in IDL(test.idl) file:
bool login(in string name, in string cipher) raises (AuthenticationException);
AuthenticationException is declared an exception in my IDL files. Then I use tao_idl to generate skeleton with below parameters:
-Wb,stub_export_macro=BASE_STUB_Export -Wb,stub_export_include=base_stub_export.h -Wb,skel_export_macro=BASE_SKEL_Export -Wb,skel_export_include=base_skel_export.h -GC
However, the generated login method in testS.h is like:
virtual ::project::UserContext * login (
const char * name,
const char * cipher) = 0;
and testI.h:
virtual
::project::UserContext * login (
const char * name,
const char * cipher);
This is strange to me. Because method declaration missing AuthenticationException exception. I believe that the method should be like:
login(..) throw(AuthenticationException)
in which custom exception, instead of CORBA standard exception, is thrown in business logic and client stub can catch these exception.
Is there something wrong in my tao_idl parameters?
No, there is nothing wrong with your tao_idl parameters, this is how the IDL to C++ mapping is defined. Older versions of IDL to C++ did use exception specifications in C++, but the recent ones don't, see the OMG IDL to C++ mapping which you can obtain from http://www.omg.org/spec/CPP.
Also the IDL to C++11 language mapping doesn't use exception specifications, this more modern C++ language mapping is also available from the OMG, see http://www.omg.org/spec/CPP11.
Your IDL method and the generated signature don't match, with IDL to C++11 your login method (with a boolean return type) in IDL looks like
virtual bool login (const std::string& name, const std::string& cipher) = 0;
Related
In the below code "RuntimeMethod1()" is an operation. It does not take any input parameters and does not give back any result.
Is this kind of method allowed in a runtime class?
I am getting compilation error for this runtime class. It says
expecting an identifier near "(" at line 7
namespace UniversalRuntimeComponent
{
[default_interface]
runtimeclass Class
{
Class();
RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
}
}
If I remove "RuntimeMethod1()" from the class then it compiles fine and generates the projection and implementation types.
If it doesn't return a result then make its return type void.
Change line 7 in your IDL to the following:
void RuntimeMethod1();
Then either copy and paste the method from auto generated .h file or just add it manually.
With the exception of constructors, all methods in MIDL 3.0 need to declare a return type. The documentation has the following to say on methods:
A method has a (possibly empty) list of parameters, which represent values or variable references passed to the method. A method also has a return type, which specifies the type of the value computed and returned by the method. A method's return type is void if it doesn't return a value.
You will have to change the MIDL to the following:
namespace UniversalRuntimeComponent
{
[default_interface]
runtimeclass Class
{
Class();
void RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
}
}
Note, that the data types declared in MIDL follow MIDL specification. This is not strictly related to the Windows Runtime type system, although all MIDL data types map to data types that can be represented in the Windows Runtime type system.
Also note, that all methods in the Windows Runtime have at least one return value at the ABI. A method declared using void in MIDL will still return an HRESULT to communicate error or success.
I have a XAML + DirectX app and I want to add static field to my "interop" class:
[Windows::Foundation::Metadata::WebHostHidden]
public ref class Direct3DInterop sealed : public Windows::Phone::Input::Interop::IDrawingSurfaceManipulationHandler
{
public:
static int VALUE = 0;
...
};
It does not compile saying "only static const integral data members can be initialized within a class".
If I change it to const static int VALUE = 0; then it still does not compile with error "a non-value type cannot have any public data members"
What am I doing wrong?
WinRT public classes have a number of limitations to ensure they are consumable by multiple languages including C++, JavaScript, and C#. This is why you are getting error C3984. You can't have public fields and instead must use properties. You'd make it a read-only property:
property int VALUE
{
int get() { return 0; }
}
It is important to remember that properties are function calls and can't usually be optimized away, so you should consider that when designing the interfaces.
If you intend to have this class only consumable by C++, consider not using a WinRT class and instead use a simple C++ class which you managed the lifetime using std::unique_ptr or std::shared_ptr. In that case, you can of course use the public field approach as always.
The original problem you got is a general C++ language restriction not specific to WinRT. Error C2864 (you are using VS 2012 from the text you posted) is a little more general with C++11 in VS2013.
I am new to visual c++, I have the following code:
ref class Book sealed
{
public:
Book(std::string title,std::string author,int year);
void setTitle(std::string title);
std::string getTitle() const;
int getYear() const;
void setYear(int year);
void setAuthor(std::string author_);
std::string getAuthor() const;
private:
std::string title_;
std::string author_;
int year_;
};
When I am trying to compile it I am getting the following error:
{ctor} signature of public member contains native type. I suppose this is because I am using an the std::string and not the Platform::String, how can I fix that?
Your ref class is not marked public itself, so it appears you are only consuming this class internally (as source) from other C++, and not intending for it to be published to other WinRT consumers.
If this is the case, you can set your constructor as internal instead of public, which will be public within this component and not visible externally. And really if that's your intended usage, then it can just be a regular 'class' instead of a 'ref class'. If you do wish to use it across the WinRT boundary but you don't need the constructor, you can make it a 'public ref class' and have the constructor marked as 'internal'. Kinda depends on your scenario.
If you instead wish to make this class public and have a public constructor which is usable across the WinRT boundary (so that it can be consumed by C#/VB/JS), then you need to use WinRT types (such as Platform::String). Within your class the storage type can still be a std::string (although I recommend using std::wstring, otherwise you need to do wide-to-narrow conversions, as Platform::Strings are wide strings).
To convert between these two types, use Platform::String::Data() to get at the underlying wchar_t* which you can use to construct a std::wstring. And similarly, Platform::String has a constructor which takes a wchar_t* (which you can get from std::wstring::c_str()).
You can't hold native types in a managed reference class.
You can only hold a pointer to an unmanaged object(a pointer is just a number after all, and that's why it's allowed).
The problem involved a JAVA call to a C-function (API) which returned a pointer-to-pointer as an argout argument. I was trying to call the C API from JAVA and I had no way to modify the API.
Using SWIG typemap to pass pointer-to-pointer:
Here is another approach using typemaps. It is targetting Perl, not Java, but the concepts are the same. And I finally managed to get it working using typemaps and no helper functions:
For this function:
typedef void * MyType;
int getblock( int a, int b, MyType *block );
I have 2 typemaps:
%typemap(perl5, in, numinputs=0) void ** data( void * scrap )
{
$1 = &scrap;
}
%typemap(perl5, argout) void ** data
{
SV* tempsv = sv_newmortal();
if ( argvi >= items ) EXTEND(sp,1);
SWIG_MakePtr( tempsv, (void *)*$1, $descriptor(void *), 0);
$result = tempsv;
argvi++;
}
And the function is defined as:
int getblock( int a, int b, void ** data );
In my swig .i file. Now, this passes back an opaque pointer in the argout typemap, becaust that's what useful for this particular situation, however, you could replace the SWIG_MakePtr line with stuff to actually do stuff with the data in the pointer if you wanted to. Also, when I want to pass the pointer into a function, I have a typemap that looks like this:
%typemap(perl5, in) void * data
{
if ( !(SvROK($input)) croak( "Not a reference...\n" );
if ( SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0 ) == -1 )
croak( "Couldn't convert $1 to $1_descriptor\n");
}
And the function is defined as:
int useblock( void * data );
In my swig .i file.
Obviously, this is all perl, but should map pretty directly to Java as far as the typemap architecture goes. Hope it helps...
[Swig] Java: Using C helper function to pass pointer-to-pointer
The problem involved a JAVA call to a C-function (API) which returned a pointer-to-pointer as an argout argument. I was trying to call the C API from JAVA and I had no way to modify the API.
The API.h header file contained:
extern int ReadMessage(HEADER **hdr);
The original C-call looked like:
HEADER *hdr;
int status;
status = ReadMessage(&hdr);
The function of the API was to store data at the memory location specified by the pointer-to-pointer.
I tried to use SWIG to create the appropriate interface file. SWIG.i created the file SWIGTYPE_p_p_header.java from API.h. The problem is the SWIGTYPE_p_p_header constructor initialized swigCPtr to 0.
The JAVA call looked like:
SWIGTYPE_p_p_header hdr = new SWIGTYPE_p_p_header();
status = SWIG.ReadMessage(hdr);
But when I called the API from JAVA the ptr was always 0.
I finally gave up passing the pointer-to-pointer as an input argument. Instead I defined another C-function in SWIG.i to return the pointer-to-pointer in a return value. I thought it was a Kludge ... but it worked!
You may want to try this:
SWIG.i looks like:
// return pointer-to-pointer
%inline %{
HEADER *ReadMessageHelper() {
HEADER *hdr;
int returnValue;
returnValue = ReadMessage(&hdr);
if (returnValue!= 1) hdr = NULL;
return hdr;
}%}
The inline function above could leak memory as Java won't take ownership of the memory created by ReadMessageHelper, since the HEADER instance iscreated on the heap.
The fix for the memory leak is to define ReadMessageHelper as a newobject in order for Java to take control of the memory.
%newobject ReadMessageHelper();
JAVA call now would look like:
HEADER hdr;
hdr = SWIG.ReadMessageHelper();
If you are lucky, as I was, you may have another API available to release the message buffer. In which case, you wouldn’t have to do the previous step.
William Fulton, the SWIG guru, had this to say about the approach above:
“I wouldn't see the helper function as a kludge, more the simplest solution to a tricky problem. Consider what the equivalent pure 100% Java code would be for ReadMessage(). I don't think there is an equivalent as Java classes are passed by reference and there is no such thing as a reference to a reference, or pointer to a pointer in Java. In the C function you have, a HEADER instances is created by ReadMessage and passed back to the caller. I don't see how one can do the equivalent in Java without providing some wrapper class around HEADER and passing the wrapper to the ReadMessage function. At the end of the day, ReadMessage returns a newly created HEADER and the Java way of returning newly created objects is to return it in the return value, not via a parameter.”
What does "Overloaded"/"Overload" mean in regards to programming?
It means that you are providing a function (method or operator) with the same name, but with a different signature.
For example:
void doSomething();
int doSomething(string x);
int doSomething(int a, int b, int c);
Basic Concept
Overloading, or "method overloading" is the name of the concept of having more than one methods with the same name but with different parameters.
For e.g. System.DateTime class in c# have more than one ToString method. The standard ToString uses the default culture of the system to convert the datetime to string:
new DateTime(2008, 11, 14).ToString(); // returns "14/11/2008" in America
while another overload of the same method allows the user to customize the format:
new DateTime(2008, 11, 14).ToString("dd MMM yyyy"); // returns "11 Nov 2008"
Sometimes parameter name may be the same but the parameter types may differ:
Convert.ToInt32(123m);
converts a decimal to int while
Convert.ToInt32("123");
converts a string to int.
Overload Resolution
For finding the best overload to call, compiler performs an operation named "overload resolution". For the first example, compiler can find the best method simply by matching the argument count. For the second example, compiler automatically calls the decimal version of replace method if you pass a decimal parameter and calls string version if you pass a string parameter. From the list of possible outputs, if compiler cannot find a suitable one to call, you will get a compiler error like "The best overload does not match the parameters...".
You can find lots of information on how different compilers perform overload resolution.
A function is overloaded when it has more than one signature. This means that you can call it with different argument types. For instance, you may have a function for printing a variable on screen, and you can define it for different argument types:
void print(int i);
void print(char i);
void print(UserDefinedType t);
In this case, the function print() would have three overloads.
It means having different versions of the same function which take different types of parameters. Such a function is "overloaded". For example, take the following function:
void Print(std::string str) {
std::cout << str << endl;
}
You can use this function to print a string to the screen. However, this function cannot be used when you want to print an integer, you can then make a second version of the function, like this:
void Print(int i) {
std::cout << i << endl;
}
Now the function is overloaded, and which version of the function will be called depends on the parameters you give it.
Others have answered what an overload is. When you are starting out it gets confused with override/overriding.
As opposed to overloading, overriding is defining a method with the same signature in the subclass (or child class), which overrides the parent classes implementation. Some language require explicit directive, such as virtual member function in C++ or override in Delphi and C#.
using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}
public class Line : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}
An overloaded method is one with several options for the number and type of parameters. For instance:
foo(foo)
foo(foo, bar)
both would do relatively the same thing but one has a second parameter for more options
Also you can have the same method take different types
int Convert(int i)
int Convert(double i)
int Convert(float i)
Just like in common usage, it refers to something (in this case, a method name), doing more than one job.
Overloading is the poor man's version of multimethods from CLOS and other languages. It's the confusing one.
Overriding is the usual OO one. It goes with inheritance, we call it redefinition too (e.g. in https://stackoverflow.com/users/3827/eed3si9n's answer Line provides a specialized definition of Draw().