I have C# portable class library for Windows 8.1 and Windows Phone 8.1. I want to write a native (unmanaged) C++ Windows application which uses this library. As far as I seen, the best practise is to expose my library as COM interface.
This seems like a simple solution but when I create Portable Class Library project, checkboxes "Make assembly COM visible" and "Register for COM interop" are disabled. Is it impossible for Portable Class Library?
What I have tried:
I manually added entry
<RegisterForComInterop>true</RegisterForComInterop>to my project and visual studio built me .tlb file without any errors.I added it to my C++ project:
#include "stdafx.h"
#import "COM\MyLib.tlb"
#include<iostream>
using namespace MyLib;
using namespace std;
int main()
{
CoInitialize(NULL); //Initialize all COM Components
IPayMeLogicPtr core = IPayMeLogicPtr(_uuidof(ComPayMeLogic));
LoginStatus res = core->Login("myLogin", "myPassword", false, PayMeSDK::Language::Language_ru, true, "");
cout << res;
return 0;
}
Generated .tlh file seems pretty fine - here it is in a gist. But when I try to run this code, it fails with an exceptions:
exception at memory location 0x74A5DAE8 (KernelBase.dll) in PayMeDemo.ComConsoleDemo.exe: 0xE0434352 (0x80131534, 0x00000000, 0x00000000, 0x00000000, 0x73A10000).
exception at memory location 0x74A5DAE8 in PayMeDemo.ComConsoleDemo.exe: Microsoft C++ exception: _com_error at location 0x00BBFADC.
Seems like it is happening on the fourth line of code in .tli (_hr fails):
inline enum LoginStatus IPayMeLogic::Login ( _bstr_t Login, _bstr_t password, VARIANT_BOOL testEnviroment, enum Language locale, VARIANT_BOOL savePassword, _bstr_t applicationToken ) {
enum LoginStatus _result;
HRESULT _hr = raw_Login(Login, password, testEnviroment, locale, savePassword, applicationToken, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
_hr is equal to 0x80131534 error (TypeInitializationException)
However, I can't imagine what types can be wrong. Login function looks like this:
LoginStatus Login(string login, string password, bool testEnviroment, Language locale, bool savePassword, string applicationToken = null);
I already tried to
- Add assembly to GAC
- Manually register assembly with Regasm.exe
Everything seems fine but exception is still the same. Is it really impossible? Should I make a non-portable library? It would be a waste of time because my library uses classes from portable...