Dll

di il
15 risposte

Dll

Salve,

con la premessa di non essere esperto in C++, vi espongo il mio problema, ho la necessità di creare una dll in c++ con all'interno delle funzioni di utility, quale, ad esempio, la lettura del seriale dell'HD, la dll deve essere richiamata da un'applicazione C#, la funzione mi deve restituire una stringa contenente il serial HD, il codice della dll è questo:

__declspec(dllexport) char* __stdcall GetHd()
    {
        WmiQueryResult res;
        res = getWmiQueryResult(L"SELECT SerialNumber FROM Win32_PhysicalMedia", L"SerialNumber");
        if (res.Error != WmiQueryError::None) {
            return NULL;
        }
        std::string strValue;
        char* pszReturn = NULL;
        for (const auto& item : res.ResultList) {
            strValue.assign(item.begin(), item.end());
            ULONG ulSize = strlen(strValue.c_str()) + sizeof(char);
            pszReturn = (char*)::CoTaskMemAlloc(ulSize);
            strcpy(pszReturn, strValue.c_str());
            break;
        }
        return pszReturn;

    }
nall'applicazione C#, linko e chiamo la funzione in questo modo:

	[DllImport("util.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string GetHd();
        
        ...
        
        string serialhd = GetHd();
        

La funzione GetHd() mi restituisce NULL, lo stesso codice testato in un'applicazione console C++, funziona bene.


Grazie

15 Risposte

  • Re: Dll

    Non puoi recuperare tutto solo con c# ? qua un esempio https://stackoverflow.com/questions/4084402/get-hard-disk-serial-number
  • Re: Dll

    Ci dai il sorgente c++ funzionante?
  • Re: Dll

    oregon ha scritto:


    Ci dai il sorgente c++ funzionante?
    Eccolo

  • Re: Dll

    gian82 ha scritto:


    Non puoi recuperare tutto solo con c# ? qua un esempio https://stackoverflow.com/questions/4084402/get-hard-disk-serial-number
    No, purtroppo questa è la richiesta del committente
  • Re: Dll

    Questo è tuo?

    https://stackoverflow.com/questions/61965879/function-in-dll-always-returns-null
  • Re: Dll

    oregon ha scritto:


    Questo è tuo?

    https://stackoverflow.com/questions/61965879/function-in-dll-always-returns-null
    si, ma non ho risolto il problema
  • Re: Dll

    Prova a vedere l'esempio 2 , https://docs.microsoft.com/it-it/dotnet/csharp/language-reference/keywords/extern
  • Re: Dll

    gian82 ha scritto:


    Prova a vedere l'esempio 2 , https://docs.microsoft.com/it-it/dotnet/csharp/language-reference/keywords/extern

    visto, il punto è che se scrivo una funzione di test che mi restituisce una semplice stringa, funziona regolarmente
    
    __declspec(dllexport) char* __stdcall Test()
        {
            char szSampleString[] = "StringaDiTest";
            ULONG ulSize = strlen(szSampleString) + sizeof(char);
            char* pszReturn = NULL;
            pszReturn = (char*)::CoTaskMemAlloc(ulSize);
            strcpy(pszReturn, szSampleString);
            return pszReturn;
        }
    
    questa funzione di test chiamata da C# funziona
    
    [DllImport("util.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            [return: MarshalAs(UnmanagedType.LPStr)]
            public static extern string Test();
            
            string miotest = Test();
            
    
  • Re: Dll

    Puoi mandare i due progetti (DLL e C#) per provare velocemente?
  • Re: Dll

    Al di la della esportazione della funzione, GetHd() è intrisecamente errata, nel senso che forzi una std::wstring a diventare una std::string senza nessuna conversione. Se il committente chiede specificatamente come tipo di ritorno un char* devi modificare così (anche se mi sembra strano dato che le stringhe C# sono native Unicode):
    
           ...
    
        const auto& item = *(res.ResultList.cbegin());
        size_t sz = WideCharToMultiByte(CP_ACP, 0, item.c_str(), (int)item.size(), 0, 0, 0,0);
        char* pszReturn = (char*) ::CoTaskMemAlloc(sz+1);
        if (!pszReturn) return nullptr;
        ZeroMemory(pszReturn, sz + 1);
        WideCharToMultiByte(CP_ACP, 0, item.c_str(), (int)item.size(), pszReturn, sz, 0, 0);
    
        return pszReturn;
    
        }
    
    Il for l'ho tolto per via del break interno che elabora solo la prima wstring del vector in WmiQueryResult.

    Ti consiglio anche di prevedere una routine per liberare la memoria lato DLL quando la la stringa ASCIIZ è stata copiata nella string del C#
  • Re: Dll

    oregon ha scritto:


    Puoi mandare i due progetti (DLL e C#) per provare velocemente?
    Dove posso inviarli?
  • Re: Dll

    shodan ha scritto:


    Al di la della esportazione della funzione, GetHd() è intrisecamente errata, nel senso che forzi una std::wstring a diventare una std::string senza nessuna conversione. Se il committente chiede specificatamente come tipo di ritorno un char* devi modificare così (anche se mi sembra strano dato che le stringhe C# sono native Unicode):
    
           ...
    
        const auto& item = *(res.ResultList.cbegin());
        size_t sz = WideCharToMultiByte(CP_ACP, 0, item.c_str(), (int)item.size(), 0, 0, 0,0);
        char* pszReturn = (char*) ::CoTaskMemAlloc(sz+1);
        if (!pszReturn) return nullptr;
        ZeroMemory(pszReturn, sz + 1);
        WideCharToMultiByte(CP_ACP, 0, item.c_str(), (int)item.size(), pszReturn, sz, 0, 0);
    
        return pszReturn;
    
        }
    
    Il for l'ho tolto per via del break interno che elabora solo la prima wstring del vector in WmiQueryResult.

    Ti consiglio anche di prevedere una routine per liberare la memoria lato DLL quando la la stringa ASCIIZ è stata copiata nella string del C#


    Ottengo lo stesso risultato, ovvero NULL
  • Re: Dll

    Posta qui il link di dropbox o un sito da cui scaricarli
  • Re: Dll

    oregon ha scritto:


    Posta qui il link di dropbox o un sito da cui scaricarli
    Ti linko tre progettini di test

    https://www.dropbox.com/s/hcwik1bgo719j76/TEST1_CONSOLE.rar

    https://www.dropbox.com/s/9usvs1kp5jj90fz/TestCSharp.rar?dl=0

Devi accedere o registrarti per scrivere nel forum
15 risposte