S
S
Sergey2014-02-26 19:20:45
Qt
Sergey, 2014-02-26 19:20:45

Using COM on the MinGW compiler

Background: initially I could not create a shortcut, due to the impossibility of loading the COM library on MinGW (in code::blocks and qt), I decided to make a crutch and compile the library on VS2013 in order to use it in my project later. Compiled the library, checked the performance - it works. I connected the library to the test project in code::blocks (to check the performance, because they have the same compiler with qt). Everything works fine, the shortcut is created. When I try to do the same in qt-creator, I get an error when loading COM. How can this be at all? Compilers for codeblocks and qt-creator are the same and this is mingw, but why does one work and the other does not.

cpp library code
// ShortCutLibrary.cpp: определяет экспортированные функции для приложения DLL.
//
 
#include "stdafx.h"
#include "ShortCutLibrary.h"
#include <iostream>
#include <shlobj.h>
#include <objidl.h>
#include <objbase.h>
#include <windows.h>
 
using namespace std;
 
bool ShowSum(LPWSTR pwzShortCutFileName,
    LPWSTR pszPathAndFileName,
    LPWSTR pszWorkingDirectory,
    LPWSTR pszArguments,
    WORD wHotKey,
    int iCmdShow,
    LPWSTR pszIconFileName,
    int iIconIndex)
{
    IShellLink * pSL;
    IPersistFile * pPF;
    HRESULT hRes;
    if (CoInitialize(NULL) != S_OK)
    {
        cout << "Невозможно загрузить COM\n";
        return false;
    }
    // Получение экземпляра компонента "Ярлык"
    hRes = CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&pSL);
 
    if (SUCCEEDED(hRes))
    {
        cout << "Создан инстанс\n";
        hRes = pSL->SetPath(pszPathAndFileName);
        if (SUCCEEDED(hRes))
        {
            cout << "Успешно установлен путь к ехе\n";
            hRes = pSL->SetArguments(pszArguments);
            if (SUCCEEDED(hRes))
            {
                cout << "Аргументы установлены\n";
                hRes = pSL->SetWorkingDirectory(pszWorkingDirectory);
                if (SUCCEEDED(hRes))
                {
                    cout << "Директория записана\n";
                    hRes = pSL->SetIconLocation(pszIconFileName, iIconIndex);
                    if (SUCCEEDED(hRes))
                    {
                        cout << "Иконка установлена\n";
                        hRes = pSL->SetHotkey(wHotKey);
                        if (SUCCEEDED(hRes))
                        {
                            cout << "Хоткей записан\n";
                            hRes = pSL->SetShowCmd(iCmdShow);
                            if (SUCCEEDED(hRes))
                            {
                                cout << "Комманды \n";
                                // Получение компонента хранилища параметров
                                hRes = pSL->QueryInterface(IID_IPersistFile, (LPVOID *)&pPF);
                                if (SUCCEEDED(hRes))
                                {
                                    cout << "связь\n";
                                    // Сохранение созданного ярлыка
                                    hRes = pPF->Save(pwzShortCutFileName, TRUE);
                                    if (SUCCEEDED(hRes))
                                        cout << "Сохранили";
                                    pPF->Release();
                                }
                            }
                        }
                    }
                }
 
            }
        }
        pSL->Release();
    }
    CoUninitialize();
    return SUCCEEDED(hRes);
}
h library code
#ifndef __TESTDLL_H
#define __TESTDLL_H
 
#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API extern "C" __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API extern "C" __declspec(dllimport) 
#endif
 
MATHFUNCSDLL_API bool ShowSum(LPWSTR pwzShortCutFileName,
    LPWSTR pszPathAndFileName,
    LPWSTR pszWorkingDirectory,
    LPWSTR pszArguments,
    WORD wHotKey,
    int iCmdShow,
    LPWSTR pszIconFileName,
    int iIconIndex);
 
#endif // __TESTDLL_H
Library call code in codeblocks and qt-creator
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
 
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    typedef bool __cdecl (*dll_func)(LPWSTR pwzShortCutFileName,
    LPWSTR pszPathAndFileName,
    LPWSTR pszWorkingDirectory,
    LPWSTR pszArguments,
    WORD wHotKey,
    int iCmdShow,
    LPWSTR pszIconFileName,
    int iIconIndex);
 
    dll_func lol = NULL;
 
    HMODULE mod = LoadLibrary("C:\\test\\ShortCutLibrary.dll");
 
    if (!mod)
        cout << "YOU CANNOT INTO DLL\n";
    else
        cout << "YOU CAN INTO DLL\n";
 
    lol = (dll_func)GetProcAddress(mod, "ShowSum");
 
    if (!lol)
        cout << "YOU CANNOT INTO DLL";
    else
        cout << "YOU CAN INTO DLL";
 
    bool a = lol(L"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\testing.lnk", L"C:\\test\\SmcServer.exe", L"C:\\", L"", 0, SW_SHOW, NULL, 0);
    cout << a;
    //lol(4,2);
 
    FreeLibrary(mod);
    return 0;
}

Application Output: Unable to load COM. (added for debug see code)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2014-10-27
@jcmvbkbc

if (CoInitialize(NULL) != S_OK)

wrong check. If CoInitialize has already been called, you will get S_FALSE, but this is not an error.
It will be right
if (FAILED(CoInitialize(NULL)))

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question