Avatar billede lau_r Nybegynder
09. august 2005 - 13:51 Der er 9 kommentarer og
1 løsning

DllImport - hvordan instantierer jeg nye instances af en C++ dll?

Jeg bruger en dll (C++) til at styre noget eksternt hardware.
Det er nemt i C# at erklære unmanaged metoder:
[DllImport("CVAPIV01.dll")]
private static extern int OpenComm(StringBuilder Com);
Mit problem er at de objekter jeg instantierer med en reference til dll'en tilsyneladende alle har fat i det samme dll-objekt.
Eks:
Hardw1.OpenComm("COM1");
Hardw2.OpenComm("COM2");
--> Hardw1 vil nu ikke længere have forbindelse til COM1, men COM2.
Hvordan tvinger jeg .Net til at loade flere objekter fra den samme dll?  Jeg har set et eksempel i C++ hvor man bruger HINSTANCE hard1 = LoadLibrary("mindll.dll");
HINSTANCE hard2 = LoadLibrary("mindll.dll");
Hvilket virker, men hvordan gør man det i C#?
Avatar billede arne_v Ekspert
09. august 2005 - 14:14 #1
Du vil formentlig kun have en instans af din DLL.

Win32 DLL'er kan kun forekomme i en instans.

En DLL er ikke det samme som et objekt.

Hvis din DLL indeholder en klasse så kan du instantiere flere objekter (instanser
af den klasse) udfra en DLL.

Hvis den DLL indeholder C funktioner (eller en klasse med ene static
fields & methods), så har du et problem. Fordi så er der kun en instans
af al "state".

Løsningen må så være at gå et niveau ned i API - hvor du formentlig
kan få en HANDLE som du kan bruge til at adskilel tingene med.
Avatar billede lau_r Nybegynder
09. august 2005 - 14:21 #2
Har du et eksempel eller et link der beskriver hvordan jeg kan få en HANDLE? Jeg ved at det kan lade sig gøre fra C++ HINSTANCE h=LoadLibrary("mindll.dll"); Så det kan ikke være ene static fields & methods.
Avatar billede arne_v Ekspert
09. august 2005 - 14:37 #3
Jeg vil da formode at:

HINSTANCE hard1 = LoadLibrary("mindll.dll");
HINSTANCE hard2 = LoadLibrary("mindll.dll");

hard1 og hard2 peger på det samme.
Avatar billede lau_r Nybegynder
09. august 2005 - 14:43 #4
Du får lige hele mit eksempel i C++ fra producenten af hardwaret:
HINSTANCE m_hdll1; // add by lxp
HINSTANCE m_hdll2; // add by lxp
//HINSTANCE m_hdll[2]; //..array mothed

void example();
{
m_hdll1 = LoadLibrary("CVAPIV01.dll");    //..com1
m_hdll2 = LoadLibrary("CVAPIV01.dll");    //..com2
}

void CDemoDlg::OnInitValue()
{
int nStatus = 0;
char  *szPage = new char[m_StarkBlock.GetLength()];
CStringToChar(m_StarkBlock,szPage);
BYTE *nPage = new BYTE[1];
memcpy(nPage,StringToHexs(szPage,nStatus),sizeof(BYTE));

CV_MF_InitValue MF_InitValue;
MF_InitValue = (CV_MF_InitValue)GetProcAddress(m_hdll1,"MF_InitValue");
nStatus = MF_InitValue(m_Address,*nPage,m_Value);

CString StrVal;
if (!nStatus)
{
StrVal.Format("Initila Value Block  %02X  (OK)",m_Value);
AddContent(StrVal,0,1);
}
else
{
CVMessage(nStatus,"Initial Value Block -",StrVal);
AddContent(StrVal,0,1);
}
}

void CDemoDlg::OnReadValue()
{
int nStatus = 0;
char  *szPage = new char[m_StarkBlock.GetLength()];
CStringToChar(m_StarkBlock,szPage);
BYTE *nPage = new BYTE[1];
memcpy(nPage,StringToHexs(szPage,nStatus),sizeof(BYTE));

int nValue = 0;
CV_MF_ReadValue MF_ReadValue;
MF_ReadValue = (CV_MF_ReadValue)GetProcAddress(m_hdll2,"MF_ReadValue");

nStatus = MF_ReadValue(m_Address,*nPage,&nValue);
CString StrVal;
if (!nStatus)
{
m_Value = nValue;
StrVal.Format("MIFARE Value Block Read(OK-) Value %02X ",m_Value);
AddContent(StrVal,0,1);
}
else
{
CVMessage(nStatus,"MIFARE Value Block Read -",StrVal);
AddContent(StrVal,0,1);
}
}
------------------------------------------------------
Det er ikke pænt, men de påstår det virker. Hvis det er rigtigt må m_hdll1 og m_hdll2 have fat på to forskellige objekter…eller?
Avatar billede arne_v Ekspert
09. august 2005 - 14:53 #5
Jeg tror (det er ikke lige den slags kode jeg er mest kendt med), at deres
kode også ville virke med kun en variabel

NB: Jeg undrer mig over at de bruger HINSTANCE - LoadLibrary returnerer
en HMODULE - jævnfør http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp
Avatar billede lau_r Nybegynder
09. august 2005 - 15:10 #6
okay... hvordan går jeg så "et niveau ned"? Kan jeg bruge HANDLE's til at skille det?

NB: Det lyder nu mærkeligt at de har lavet et eksempel til mig hvor de opretter et array med instances?! Jeg har forklaret dem mit problem med flere enheder tilsluttet og fået ovenstående som svar.
Avatar billede arne_v Ekspert
09. august 2005 - 19:40 #7
Jeg har lige checket.

C:\e3>type d.c
#include <windows.h>

BOOL APIENTRY DllMain( HANDLE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved
                    )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

__declspec(dllexport) int test(int a, int b)
{
  return a+b;
}

C:\e3>type test.c
#include <windows.h>
#include <stdio.h>

typedef int (*DF)(int a, int b);

int main()
{
  HINSTANCE dll1,dll2;
  DF fncptr1,fncptr2;
  dll1 = LoadLibrary("d.dll");
  dll2 = LoadLibrary("d.dll");
  fncptr1 = (DF)GetProcAddress(dll1,"test");
  fncptr2 = (DF)GetProcAddress(dll2,"test");
  printf("%d %d\n",(int)dll1,fncptr1(12,34));
  printf("%d %d\n",(int)dll2,fncptr2(12,34));
  return 0;
}

C:\e3>build2

C:\e3>gcc -c d.c -o d.obj

C:\e3>gcc -s -shared -Wl,--export-all,--kill-at d.obj -o d.dll

C:\e3>gcc test.c -o test.exe

C:\e3>test
1779695616 46
1779695616 46

C:\e3>

2 x LoadLibrary giver samme handle !
Avatar billede arne_v Ekspert
09. august 2005 - 19:42 #8
jeg kan ikke gennemskue dit problem

måske kan du nøjes med en dll ref

måske skal du bruge det som OpenComm returnerer

måske skal du finde nogle andre metoder
Avatar billede lau_r Nybegynder
14. november 2006 - 11:54 #9
jeg endte med at skrive en ny driver selv. Vil du have point arne_v?
Avatar billede arne_v Ekspert
14. november 2006 - 12:54 #10
gerne
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester