I currently had a pending question open - however after working on it I ran onto a new problem and the errors that I was getting while attempting to build it were:
Error 1 error C2695: 'MyEventsSink::OnSomethingHappened': overriding virtual function differs from 'Library::IEventsSink::OnSomethingHappened' only by calling convention
Error 2 error C2695: 'MyEventsSink::SomeTest': overriding virtual function differs from 'Library::IEventsSink::SomeTest' only by calling convention
I tried goggling regarding this error but I could not figure it out.
Here is what I am doing , I have a managed C# dll class library which is being consumed by a native C++ application. The code for C# interface is as follows and the implemention of this interface is in C++.
The C# code is
[ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("fdb9e334-fae4-4ff5-ab16-d874a910ec3c")]
public class IEventsSinkImpl : IEventsSink
{
public void OnSomethingHappened()
{
//Doesnt matter what goes on here - atleast for now
}
public void SomeTest(IEventsSink snk)
{
//When this is called - it will call the C++ code
snk.OnSomethingHappened();
}
}//end method
And its implemetation code in C++ is
class MyEventsSink : public Library::IEventsSink
{
public:
MyEventsSink() {}
~MyEventsSink() {}
virtual HRESULT OnSomethingHappened()
{
std::cout << "Incredible - it worked";
}
virtual HRESULT SomeTest(IEventsSink* snk)
{
//Doesnt matter this wont be called
}
};
Apparently during the build process VS2010 complains of the above mentioned errors. Any suggestions on how I could resolve those errors.
Try using __stdcall calling convention:
virtual HRESULT __stdcall OnSomethingHappened()
Normally, C++ uses the __cdecl calling convention, where the caller removes the parameters from the stack after the call. Most Windows API functions including COM use __stdcall where the callee removes the parameters from the stack.
Obviously, when you override a virtual function, the calling convention of both functions must be the same, because the function call is resolved at runtime.
Related
Currently I'm using a third party DLL for a printer. It's a C# wrapper for a C++ DLL, so it can be used in a C# application. The method for printing contains a callback function that should be called when printing is done. However, I can't get it to work, so I'm wondering if I'm implementing it correctly.
The (shortened) method of this print and callback function is:
public class PrinterWrapper
{
public uint Print(CallbackFunction callbackFunction);
public delegate void CallbackFunction();
}
In another class I'm using the print function and try to test the callback this way:
class Foo {
private void callback() {
{
Console.WriteLine("Test");
}
public void Print() {
{
PrinterWrapper wrapper = new PrinterWrapper();
wrapper.Print(this.callback);
wrapper.Print(new PrinterWrapper.CallbackFunction(this.callback));
}
}
I've tried both version of calling the Print method (both should be the same), but I'm not getting a callback. Instead, I get an APPCRASH just when the print is ready. Did some searching, found out I could catch the exception with the setting
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true" />
</runtime>
It tells me it's a read/write memory protection exception. The event log also shows an error, right before my application crashes:
Application: Application.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
So it looks like the third party DLL is trying to access memory it doesn't have access to. The documentation says that the callback argument is a pointer (that's for the original C++ DLL). There is no documentation for the C# wrapper DLL.
With this info, did I correctly make use of the callback function or do I have to change something to get it working?
Had a wrong implementation of the callback delegate. Fixed it and it now works.
I have 2 components:
- .Net Core Application running on Ubuntu OS.
- C++ shared library (.so)
Now I want C++ component to be able to call .Net Core method, either passing interface to C++ component which will use this interface to callback method implementation or passing method as a parameter to C++ component.
High-level example what I am trying to achieve:
C# component :
public interface IDevice
{
void OnDataAvailable(string data);
}
public class Device: IDevice
{
[DllImport("sampleCPPLibrary.so")]
private static extern int SetReceiver(IDevice receiver);
public void OnDataAvailable(string data)
{
Console.WriteLine(data);
}
public void Initialize()
{
SetReceiver(IDevice(this))
}
}
C++ component:
extern "C" {
void SetReceiver(IReceiver * receiver)
{
receiver->OnDataAvailable(10);
}
}
Basically, what I am trying to do is just to pass some kind of "callback" to C++ component and call this "callback" when some event occurs in C++ component.
See See this issue from comments I constructed code where C# calls C and gives it callback delegate. Thus from C then it calls C#, and passes additional int type argument. See comments here from endurox project, and attached c-callback.tar.gz for working example.
I'm working on some code that is not mine, and it passes an argument in c++ to a (managed COM) c# method that doesn't have any parameters. The code works fine, but I don't know why.
Can someone explain what's going on or point me to the c++ constructs that make it possible?
Here's the code:
//---------- C++ ----------
#import "wrapper.tlb" named_guids raw_interfaces_only
BSTR b;
m_wrapper->getException(&b);
CW2A conv(b);
std::string s(conv);
if (! s.empty() ) {
//Perform exception processing
{
//---------- C# Managed COM ----------
public class wrapper : Iwrapper
{
private exceptionStr = String.Empty; // 'exceptionStr' set elsewhere in C# for an eventual pull by C++
public string getException()
{
return exceptionStr;
}
//... other C# methods that may set 'exceptionStr'
}
The COM standard interface does not allow return parametres, since any function returns an HRESULT. So what appear to be as a return value in the COM object in C# is marshalled as a reference in the C++ side.
Basically my code is looks like below
Managed.dll
Managed.cs
class MyManagedClass
{
public ShowMessage()
{
System.out.println("My Message");
}
}
Wrapper.dll
ref class Wrapper
{
};
Native.lib
class NativeClass
{
public:
void NativeMessage()
{
cout<<"Print Message";
}
}
Main
void main
{
NativeClass ob;
ob.NativeMessage();
}
my issue is whenever the "ob.NativeMessage();" called, somehow MyManagedClass::ShowMessage() has to be triggered.
And more impotent Native.lib linked in Wrapper.dll and Wrapper.dll referenced in Managed.dll.
Can any one help me on this.
If you're running strictly from a C++ environment, you will want to host a .NET runtime in your C++ application. If you're running from a .NET environment, that part is already done and you will need to pass a delegate to the C++ code to be called later (this, by the way, is fraught with problems as the .NET runtime up to at least version 3.0 can and will garbage collect delegates out from under you).
I am working on a project that requires implementing am unmanaged windows DLL. The DLL is used to communicate with a USB device. My code is in C# and WPF.
To initialize the DLL I call a function called:
InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
When calling this function I have to pass a struct called dllInitParams and the Handle that the control is bound to.
I am using DllImport for function pointer as such:
[DllImport("myDll.dll")]
public static extern void InitTimerDll(Int32 wHandle, ref dllInitParams initParams);
Here is my struct:
public struct dllInitParams
{
public UInt16 simp;
public UInt16 simt;
}
All of the above are in a separate class called myDllInterface.cs. Here is how I call the InitTimerDll function from my WPF form:
public IntPtr Handle
{
get { return (new System.Windows.Interop.WindowInteropHelper(this)).Handle; }
}
private void initTime_Click(object sender, RoutedEventArgs e)
{
myDllInterface.dllInitParams initParams = new myDllInterface.dllInitParams();
initParams.simp = 0;
myDllInterface.InitTimerDll(this.Handle.ToInt32(), ref initParams);
}
The first part of the above code explains how I get the handle and the initTime_Click shows how I initialize the struct, call the initTimeDll function by passing the handle and the struct to it. I have copied the dll file in the directory that the code runs in. My code compiles just fine but it creates an error when I click on the initTime button.
Error:
An unhandled exception of type 'System.AccessViolationException' occurred in ProbeCTRL.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Why is this happening?
Without knowing exactly what the InitTimerDll() function does with the 'this' pointer, I would focus on the params structure. Try adding a structure layout markup like the following:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct dllInitParams
{
public UInt16 simp;
public UInt16 simt;
}
Also, double check that your structure is complete and accurate.
I found the problem. The code is fine the problem was the dll file, which was corrupted. A proper copy of the dll file took care of the problem. When using dll in your codes it is quite important to make sure you have accurate information, function calls, data types to passed and so on.
Thanks everyone for your help.
Have a look at the PInvoke tutorial: http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx
as Jim Gomes points out:
[StructLayout(LayoutKind.Sequential)]
or something similar is definitely important.
Also, you're only initializing one of the variables in your struct.