stack in AtlAdvise trying to create a connection between OPC server and the client (callback object) - com

Create Instance of Callback Object using an ATL template
CComObject<COPCDataCallback>::CreateInstance(&pCOPCDataCallback);
pCbUnk = pCOPCDataCallback->GetUnknown();
it stacked at
HRESULT hRes = AtlAdvise(m_IOPCGroupStateMgt, // [in] IUnknown Interface of the Connection Point
pCbUnk, // [in] IUnknown Interface of the Callback object
IID_IOPCDataCallback,// [in] Connection Point ID: The OPC Data Callback
m_dwAdvise // [out] Cookie that that uniquely identifies the connection
);
unhandled exception at XXXX ntdll.dll
before that I added ATL support to the MFC project
https://stackoverflow.com/a/8046824/4270170
any ideas to solve this issue?
thanks.

It seems to be my fault that the type of the fourth param of AtlAdvise is DWORD,but there is something wrong with this param I set.And now everything goes well.Thank you all.

Related

Pass callbacks with managed parameters and return types between managed and unmanaged C++

I am writing a native C++ project with a managed C++ wrapper that can receive and invoke callbacks from C#. The managed side should be able to retrieve back that callback and trigger on the managed environment as well.
The signature of the said callback is:
// Native C++
typedef EvaluateResult (*NativeFunction) (std::vector<EvaluateResult> args);
// Managed C++ wrapper
delegate EvaluateResultWrapper^ ManagedFunction (List<EvaluateResultWrapper^> args);
The EvaluateResultWrapper is the managed wrapper class for the native class EvaluateResult. The conversion between the EvaluateResult is:
EvaluateResult result;
EvaluateResultWrapper^ wrapper = gcnew EvaluateResultWrapper (result);
result = EvaluateResult (*wrapper.original);
I want to implement the constructor EvaluateResultWrapper::EvaluateResultWrapper (ManagedFunction^ func) that can roughly do the following:
// NOTE: Pseudo code
void EvaluateResultWrapper::EvaluateResultWrapper (ManagedFunction^ func) {
this->func = func; // Store the func as a member to avoid GC
// original is the pointer to the EvaluateResult that this object is wrapping around
this->original = new EvaluateResult ([&func](std::vector<EvaluateResult> args) -> EvaluateResult {
List<EvaluateResultWrapper^>^ argsList; // Convert args from vector to List. Assuming it is done under the hood
EvaluateResultWrapper^ wrapper = func->Invoke (argsList); // Invoke the managed callback
return EvaluateResult (wrapper.GetOriginal ()); // Convert the managed result to the native counterpart
});
}
I know the above code will not work, but the idea I should be able to wrap the managed callback with codes that able to do conversion of both the callback arguments and return types, so that it is native friendly.
Ideally, I can also do the other way around (not important)
// NOTE: Pseudo code
ManagedFunction^ EvaluateResultWrapper::GetFunction (ManagedFunction^ func) {
// if the callback is set by the managed side, return the same callback back
if (this->func != nullptr) return this->func;
// Otherwise, the callback is a native one
NativeFunction nativeFunc = this->original->GetFunction ();
return gcnew ManagedFunction ([&nativeFunc] (List<EvaluateResultWrapper^>^ args) -> EvaluaResultWrapper {
std::vector argsList; // Convert the args from List back to vector. Assuming it is done under the hood
EvaluateResult result = nativeFunc (argsList); // Invoke the native function
return gcnew EvaluateResultWrapper (result); // Convert the native result into the managed one
});
}
I wonder whether this can be done?
A little bit of context: I am writing an external scripting system on native C++ for our games (similar to Lua scripting). The EvaluateResult is a class representing an evaluation result of any statement. It is basically a value coupled with the type. The type can be either number, boolean, string, array, object, or in this case: function callback.
The function callback can be either set within the native C++ (when the interpreter pass the user-defined function in the scripts) or a function set by the host (managed side).
The idea is the host (C# side) should be able to define and set functions into the memory (defining print() function to print into the host console for example). The callback is wrapped as an EvaluateResult class before storing into the the scripting memory.
For inspection purpose, C# side must be able to get the function callback. Therefor, the ability to get the function is nice to have (but not important, since I can always instruct the native side to execute the function for me)

How to use PostMessage with WM_COPYDATA for sending string message

I have two windows applications. First one a windows forms application. The second one a console application. I have to send a message from the console application to the forms application. I registered broadcast message and using ::PostMessage function was able to send a numeric message to the forms application. But I am not able to send string message. Please find my code below:-
// Sending Message (Console Application)
#define RT_UI_MSG (WM_USER+1)
UINT msg_id = RegisterWindowMessage("Test-UI");
LPTSTR lpszString = "Hello";
COPYDATASTRUCT cds;
cds.dwData = 1; // can be anything
cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
cds.lpData = &lpszString;
::PostMessage(HWND_BROADCAST, msg_id, WM_COPYDATA, (LPARAM)(LPVOID)&cds);
// Receiving Message (Forms Application)
BEGIN_MESSAGE_MAP(CRTUIDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CRTUIDlg::OnBnClickedOk)
ON_REGISTERED_MESSAGE(temp, OnRTUIMsg)
ON_BN_CLICKED(IDC_BUTTON1, &CRTUIDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
UINT temp = RegisterWindowMessage(L"Test-UI");
LRESULT CRTUIDlg::OnRTUIMsg(WPARAM wParam, LPARAM lParam)
{
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
if (pcds->dwData == 1)
{
LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
// do something with lpszString...
}
return 0;
}
Kindly help me understand what I am doing wrong and get this working
There is no way to PostMessage a WM_COPYDATA. The system needs to know when to free the internal buffer used to marshal the data. And this is known only when you send, not when you post a message.
See Why can't I PostMessage the WM_COPYDATA message, but I can SendMessageTimeout it with a tiny timeout?
WM_COPYDATA states the following:
"The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data."
But you are including a pointer to the source application heap (lpszString) into the structure which is not supported, because the heap of the source application is not accessible to the target application. WM_COPYDATA will copy that pointer as is, it will not copy the string referenced by the pointer.
I suggest looking at the example in WM_COPYDATA, the example seems to do what you need but instead of passing a string from the heap, it copies the string into the stack using a char array.
This is the link to the example:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms649009(v=vs.85).aspx

Passing the this pointer to a constructor

I'm trying to write a program in D that involves a Server class which creates new Client objects when new clients join. I want to pass the server object to the clients when they created, however when later I try to access the Server object from the client, my program stops with error code -11. I've googled it but found nothing.
I've successfully recreated this behavior in the following snippet:
import std.stdio;
class Server
{
public:
int n;
Client foo() //Foo creates a new client and passes this to it
{return new Client(this);}
}
class Client
{
public:
this(Server sv) //Constructor takes Server object
{sv=sv;}
Server sv;
void bar() //Function bar tries to access the server's n
{writeln(sv.n);}
}
void main()
{
Server s = new Server; //Create a new server object
Client c = s.foo(); //Then ask for a client
//c.sv=s; //!!!If I leave this line in the source then it works!!!
sv.n=5; //Set it to a random value
c.bar(); //Should print 5, but instead crashes w/ error -11
}
If I uncomment the c.sv=s line, then is magically works, which I don't understand.
So why is that if I set sv in the constructor then it crashes, but if I set it later then it works?
EDIT:
Adding writeln(sv) to the bar function prints null, so it can cause the crash. But why is it null?
{sv=sv;}
This line is the mistake. It sets the local sv, not the class instance. Try this.sv = sv; instead to set the instance member to the local.
edit: so since you never set the instance variable, it remains uninitialized - defaulting to null.

Using Marshal::GetFunctionPointerForDelegate and calling a callback from unmanaged code causes a buffer overrun when quitting application

I am using Visual Studio 2008 with .NET Framework 3.5 and making a C++/CLI/.NET Forms application; an editor for a game. All the game code other than the editor is in pure C++. I'm getting to a point where I need callbacks in the Forms code to be called from unmanaged code.
I'm using GetFunctionPointerForDelegate.
First I have these in my Form class:
public: delegate void ADelegate(Int32, float, float, float, Int32);
public: static ADelegate^ delegateInstance;
Then I set up the callback in the Form constructor:
// Set up World Objects callback
typedef void (__stdcall *WorldLocationUpdateCallback)(Int32, float, float, float, Int32);
WorldLocationUpdateCallback _callback;
// Create an instance of a delegate, using GetFunctionPointerForDelegate
delegateInstance = gcnew ADelegate( this, &MainForm::InitWorldObjectPane );
// Convert the delegate to a pointer
IntPtr anIntPtr = Marshal::GetFunctionPointerForDelegate( delegateInstance );
// Cast the pointer into a function pointer
_callback = static_cast<WorldLocationUpdateCallback>(anIntPtr.ToPointer());
CEditorUI::UI()->setWorldLocationUpdateCallback( (void*)_callback );
So I store the pointer and in the unmanaged code, call the callback early on in the initialization of my app, from a different thread:
// Set up World Object pane in editor to use this map/maptile/etc
{
typedef void (*WorldLocCallback)(int, float, float, float, int);
void* _callback = CEditorUI::UI()->getWorldLocationUpdateCallback();
int _mapId = charGfxObj->getMapId();
float _posX = charGfxObj->getPos().x;
float _posY = charGfxObj->getPos().y;
float _posZ = charGfxObj->getPos().z;
int _tileRadius = TILE_RADIUS;
((WorldLocCallback)(_callback))( _mapId, _posX, _posY, _posZ, _tileRadius );
}
Everything works perfectly, functionally in my app, all the way until when I close the application. It always dies with a Buffer overrun error in the calling thread, the call stack being rather unhelpful:
editor.exe!__crt_debugger_hook() Unknown
>editor.exe!__report_gsfailure() Line 298 + 0x7 bytes C
editor.exe!__CorExeMain#0() + 0xe3 bytes C++
The kicker here is that it crashes even if the callback does literally nothing at all. All I have to do to cause the crash is to enable that last line of code that calls the callback. With that line disabled, no problems. Keep in mind the crash happens only when quitting, and not when actually using the callback.
Any recommendations to try?
After an entire day messing with this and searching for other related things, I somewhat solved this, in case anyone else has this issue.
Moving the delegate declaration outside the class and decorating it with:
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
...solved it for me. Apparently the stack clearing effect of cdecl solves the overrun.

RSACryptoServiceProvider.ImportParameters ObjectDisposedException

We have a webservice we would like to sign an incoming request and send it further. We are using the static object of System.Security.Cryptography.RSACryptoServiceProvider and every instance is using the same static object to sign it. I read on microsoft that the static object is thread safe for this class.
Problem is that on heavy load on webservice, the signing fails with below exception:
`Exception Type: System.ObjectDisposedException
Message: Safe handle's handle field can only be set if the safe handle is not closed and has a ref count of 1.
ObjectName:
Data: System.Collections.ListDictionaryInternal
TargetSite: Void _ImportKey(System.Security.Cryptography.SafeProvHandle, Int32, System.Security.Cryptography.CspProviderFlags, System.Object, System.Security.Cryptography.SafeKeyHandle ByRef)
HelpLink: NULL
Source: mscorlib
StackTrace Information
****************************
at System.Security.Cryptography.Utils._ImportKey(SafeProvHandle hCSP, Int32 keyNumber, CspProviderFlags flags, Object cspObject, SafeKeyHandle& hKey)
at System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters parameters)`