API Support Forum
OEC API > API Support > C++ COM Wrapper CancelOrder Not Functioning
Author Topic: C++ COM Wrapper CancelOrder Not Functioning
(38 messages, Page 1 of 2)
Moderators: VPfau
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 20, 2020 @ 12:21 PM             Msg. 1 of 38
Attempting to cancel an order, my software is crashing from what seems to be something in the COM Wrapper.

I took the code from the code examples on bitbucket. This is the code I am using to cancel an order:,

IOrderPtr order = GetOrderPtr((LPCTSTR)id); //returns the order pointer given a specific id
if(order)
GFApi()->Orders->CancelOrder(order->id, GF_Api_COM::SubmissionType_Manual, NULL);

Here is the callstack of my crash when this function finishes.

KernelBase.dll!_RaiseException@16() Unknown
clr.dll!RaiseTheExceptionInternalOnly(class Object *,int,int) Unknown
clr.dll!UnwindAndContinueRethrowHelperAfterCatch(class Frame *,class Exception *) Unknown
clr.dll!MarshalNative::GetIDispatchForObjectNative(class Object *,bool) Unknown
mscorlib.ni.dll!7002023d() Unknown
[Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]
mscorlib.ni.dll!701dc279() Unknown
mscorlib.ni.dll!7002b81c() Unknown
mscorlib.ni.dll!7002b3bd() Unknown
clr.dll!_CallDescrWorkerInternal@4() Unknown
clr.dll!CallDescrWorkerWithHandler(struct CallDescrData *,int) Unknown
clr.dll!MethodDescCallSite::CallTargetWorker(unsigned __int64 const *) Unknown
clr.dll!CLRToCOMLateBoundWorker(class ComPlusMethodFrame *,class ComPlusCallMethodDesc *) Unknown
clr.dll!_CLRToCOMWorker@8() Unknown
clr.dll!_GenericComPlusCallStub@0() Unknown
175e53bd() Unknown
175e536e() Unknown
175e5440() Unknown
0375cab4() Unknown
0375ca3c() Unknown
0375c9d8() Unknown
mscorlib.ni.dll!6f8a2e01() Unknown
mscorlib.ni.dll!6f8c8604() Unknown
mscorlib.ni.dll!6f8c8537() Unknown
mscorlib.ni.dll!6f8c84f4() Unknown
mscorlib.ni.dll!6f8a2d5b() Unknown
clr.dll!_CallDescrWorkerInternal@4() Unknown
clr.dll!CallDescrWorkerWithHandler(struct CallDescrData *,int) Unknown
clr.dll!MethodDescCallSite::CallTargetWorker(unsigned __int64 const *) Unknown
clr.dll!ThreadNative::KickOffThread_Worker(void *) Unknown
clr.dll!ManagedThreadBase_DispatchInner() Unknown
clr.dll!ManagedThreadBase_DispatchMiddle() Unknown
clr.dll!ManagedThreadBase_DispatchOuter() Unknown
clr.dll!ManagedThreadBase_FullTransitionWithAD() Unknown
clr.dll!ThreadNative::KickOffThread(void *) Unknown
clr.dll!Thread::intermediateThreadProc(void *) Unknown
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown

Will you please look into this for me and let me know if this is something I am not doing correct on my end?

Thanks.

P.S. Is this the correct place to be posting these issues I am seeing with the COM Wrapper? Is the call stack helpful at all?
JSmith5611
Posts: 187
Joined:


Posted: May 20, 2020 @ 01:10 PM             Msg. 2 of 38
Unfortunately, COM wrapper call stacks tend to be... not helpful at all.

My guess is that you're not getting the order correctly from your
IOrderPtr order = GetOrderPtr((LPCTSTR)id);
line. Yes, you check to see if the orderptr is null, but it still might not be valid.
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 20, 2020 @ 03:25 PM             Msg. 3 of 38
I am using the same way to get the order pointer the same way in bitbucket:

GF_Api_COM::IOrderPtr order = GFAPI()->Orders->Get_2(GFAPI()->Orders->CreateID(dlg.m_TicketNumber));

I should have added, it does delete the order correctly, but it crashes the application in doing so. So I do believe I am getting the order correctly.

Is there another way I should be doing this?
Edited by RWare2020 on May 20, 2020 03:25 PM
JSmith5611
Posts: 187
Joined:


Posted: May 21, 2020 @ 08:05 AM             Msg. 4 of 38
Can I see your code that converts your (LPCTSTR)id to an int or long?

I've testing the example code, and it is cancelling orders just fine.. not sure why you cannot.
Also, what version of the COM api do you have installed?
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 21, 2020 @ 10:12 AM             Msg. 5 of 38
I use std::stol(id)

Here it is:

IOrderPtr GetOrderPtr(const std::string& id)
{
GF_Api_COM::IOrderPtr order = GFApi()->Orders->Get_2(GFApi()->Orders->CreateID(std::stol(id)));
return order;
}

There are times when it doesn't crash and other times that it does.

I have version 4.0.1.39 32 bit installed for the COM api.

Thanks for your help
Edited by RWare2020 on May 21, 2020 01:24 PM
JSmith5611
Posts: 187
Joined:


Posted: May 26, 2020 @ 02:40 PM             Msg. 6 of 38
I have been trying repeatedly to replicate this issue to no avail. is there anyway you can send me your code so i can test myself?
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 26, 2020 @ 03:08 PM             Msg. 7 of 38
Here are a couple more things that could potentially help you replicate the issue:

1. I am using sim.gainfutures.com to connect with port id 9210.
2. I have been able to duplicate it multiple times with the NASDAQ Mini contract NQM20
3. Deleting on a contract such as Euro FX 6EM20 seems to work most, if not every time.
4. I am seeing this same issue when closing out a position as well. This is closing out a position using a market, stop, or limit order. It closes the position, but crashes with a COM callstack, but this happens with every symbol, not just certain ones. This has happened to me 100% of the time on multiple contract symbols.
5. I am using the value that comes back from OrderList()->Get()->GetAt(i)->TicketNumber->Value to delete the orders

I can't send you my code but here are snippets that hopefully will help to diagnose:

void apiGainFutures::UpdateOrders()
{
GF_Api_COM::IOrderListPtr orders = GFApi()->Orders->Get();
for(int i=0; i Count; ++i)
{
GF_Api_COM::IOrderPtr order = orders->GetAt(i);
GainFuturesOrder ord;
CString str;
str.Format("%d",order->TicketNumber->Value);
ord.m_OrderID = str;

//fill in other values for the order...
}
}

void apiGainFutures::DeleteOrder(const std::string& strOrderID)
{
CString id = strOrderID.c_str();
auto& itr = m_Orders.find((LPCTSTR)id);
if (itr != m_Orders.end())
{
GF_Api_COM::IOrderPtr order = GetOrderPtr((LPCTSTR)id);
if(order)
GFApi()->Orders->CancelOrder(order->id, GF_Api_COM::SubmissionType_Manual, NULL);
}
}

IOrderPtr apiGainFutures::GetOrderPtr(const std::string& id)
{
long val = std::stol(id);
GF_Api_COM::IOrderListPtr orders = GFApi()->Orders->Get();
for (int i = 0; i Count; i++)
{
if (orders->GetAt(i)->TicketNumber->Value == val)
return orders->GetAt(i);
}

return NULL;
}
Edited by RWare2020 on May 26, 2020 03:09 PM
Edited by RWare2020 on May 26, 2020 03:13 PM
JSmith5611
Posts: 187
Joined:


Posted: May 28, 2020 @ 07:09 AM             Msg. 8 of 38
Even with your code, I have been unable to reproduce this. However, reading through this thread again.. i think we're looking in the wrong place.

"I should have added, it does delete the order correctly, but it crashes the application in doing so. So I do believe I am getting the order correctly."

This, combined with your other order issues.. I think you have an event registration issue.
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 28, 2020 @ 12:03 PM             Msg. 9 of 38
How do you suggest I go about testing the event registration issue?

I have copied and pasted the code from the bitbucket example for GFAPIEvents and have made sure that all the functions have been overridden with a body in my message handling class and I'm still having an issue.

Thanks again for helping me through this.
JSmith5611
Posts: 187
Joined:


Posted: May 28, 2020 @ 01:33 PM             Msg. 10 of 38
I just double checked. I changed the _ATL_FUNC_INFO for OnOrderConfirmedInfo in the example to be incorrect (said there were 2 passed parameters when there are actually 3)

When sending an order, application crashed with the same call stack as yours.

Unfortunately figuring out which event in your case is the issue will be... difficult. COM, particularly in c++ isn't exactly easy to use.

May I ask why you decided on this route instead of .NET?

Jason Smith

Edited by JSmith5611 on May 28, 2020 01:35 PM
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 28, 2020 @ 01:40 PM             Msg. 11 of 38
My _ATL_FUNC_INFO OnOrderConfirmedInfo shows this:

_ATL_FUNC_INFO OnOrderConfirmedInfo = { CC_STDCALL, VT_EMPTY, 3,{ VT_DISPATCH, VT_DISPATCH, VT_DISPATCH } }; so it is correctly showing 3 parameters and I have been able to receive a callback to that function before.

Another one I just found is when I am using GFApi()->Contracts->Load->request(builder);

It's just strange as to why deleting an order would sometimes fail the callback and sometimes it won't.

Our whole application is written in MFC, that is why we chose to go the route of COM.

Thanks
JSmith5611
Posts: 187
Joined:


Posted: May 28, 2020 @ 01:42 PM             Msg. 12 of 38
i picked that particular event to corrupt because it would be easy to test.
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 28, 2020 @ 03:04 PM             Msg. 13 of 38
Oh okay that makes sense.

If there is an event registration issue and I have copied the code straight from the BitBucket example, does that mean there is an issue with the example code?

I'm not quite sure what steps to take to diagnose the problem. Do you see this being something on my end or your end?

If it is something on my end, do you have some suggestions as to how to nail down the issue?

Thanks
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: May 29, 2020 @ 10:37 AM             Msg. 14 of 38
If it helps out at all here is the exact code I use when the callback fails for contract load:

IBaseContractPtr bc = GFApi()->Contracts->Base->Get_3("OES");
if (bc && bc->IsOption)
{
GF_Api_COM::IContractLoadRequestBuilderPtr builder;
builder.CreateInstance(__uuidof(GF_Api_COM::ContractLoadRequestBuilder));
IContractLoadExpressionBuilderPtr exprBuilder;
exprBuilder.CreateInstance(__uuidof(GF_Api_COM::ContractLoadExpressionBuilder));
exprBuilder->WithBaseContractID(bc->id);
builder->WithExpression(exprBuilder->Build());
builder->WithResultCount(1); //I have tried with no result count as well and with a result count of 20, still same result
GFApi()->Contracts->Load->request(builder->Build());
}

I can give you the demo account I login to through email if that would help out at all.

Let me know if I can do anything to help diagnose further.
JSmith5611
Posts: 187
Joined:


Posted: Jun 01, 2020 @ 03:08 PM             Msg. 15 of 38
There was a problem with the contractloadrequestBuilder.
It was fixed in version 4.0.1.42
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: Jun 01, 2020 @ 05:05 PM             Msg. 16 of 38
Unfortunately I am having the same call stack fail when receiving a callback for all three of my cases still:
* Deleting Orders
* Closing a Position
* Contract Load Request
JSmith5611
Posts: 187
Joined:


Posted: Jun 10, 2020 @ 12:15 PM             Msg. 17 of 38
I'm sorry that i haven't posted here in a little while. I have been trying to replicate your issues to no avail. I do want to help.
Jason Smith
JSmith5611
Posts: 187
Joined:


Posted: Jun 11, 2020 @ 08:22 AM             Msg. 18 of 38
I just did a test of doing repeated contract load requests.. all of them worked just fine for me.

Though, i did find out one thing that can cause issues. If you install a new version of the COM api without manually uninstalling the old version first. Otherwise, you can end up with duplicate registry keys, and compiler/COM can get confused of which version should be used.

The only way i was able to fix this on my pc, was to manually remove registry keys associated with the COM lib... which wasn't exactly a safe thing to do.
Jason Smith
RWare2020
Posts: 205
Joined: Feb 11, 2020


Posted: Jun 11, 2020 @ 10:02 AM             Msg. 19 of 38
That could very well be it. I did not uninstall the old COM api before installing the new one.

Can you give me some guidance on what registry values should be removed? Do you have a list of your used registry keys I can go through and remove?

Thanks for your help figuring this out.
Edited by RWare2020 on Jun 11, 2020 10:18 AM
JSmith5611
Posts: 187
Joined:


Posted: Jun 11, 2020 @ 12:47 PM             Msg. 20 of 38
Please be VERY careful with your registry editing. it is WAY too easy to completely screw up a windows installation.

first, uninstall the COM api, that will get rid of some of the keys

all the changes are going to be in [HKEY_CLASSES_ROOT], so back up that tree first.

I ended up searching for "file:///C:/Program Files (x86)/GAIN/GFAPI COM/GF.Api.COM.DLL" across all values, and deleting any key that had references to it.

For example I had these entries:

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}]
@="GF.Api.COM.GFComClient"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\Implemented Categories]

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\InprocServer32\4.0.1.21]
"Class"="GF.Api.COM.GFComClient"
"Assembly"="GF.Api.COM, Version=4.0.1.21, Culture=neutral, PublicKeyToken=b6b45f27e2749b17"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Program Files (x86)/GAIN/GFAPI COM/GF.Api.COM.DLL"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\InprocServer32\4.0.1.26]
"Class"="GF.Api.COM.GFComClient"
"Assembly"="GF.Api.COM, Version=4.0.1.26, Culture=neutral, PublicKeyToken=b6b45f27e2749b17"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Program Files (x86)/GAIN/GFAPI COM/GF.Api.COM.DLL"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\InprocServer32\4.0.1.30]
"Class"="GF.Api.COM.GFComClient"
"Assembly"="GF.Api.COM, Version=4.0.1.30, Culture=neutral, PublicKeyToken=b6b45f27e2749b17"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Program Files (x86)/GAIN/GFAPI COM/GF.Api.COM.DLL"

[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}\InprocServer32\4.0.3.17]
"Class"="GF.Api.COM.GFComClient"
"Assembly"="GF.Api.COM, Version=4.0.3.17, Culture=neutral, PublicKeyToken=b6b45f27e2749b17"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///C:/Program Files (x86)/GAIN/GFAPI COM/GF.Api.COM.DLL"

I deleted [HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{8DA63571-5DF5-4C4B-992B-72FECC2C387A}] and everything underneath it.
Jason Smith