Sziasztok!
Adott egy léptetőmotor vezérlőkártya, driver (ADVMOT.dll), annak az sdk-ja C#-ra és C-re egyaránt.
C-ben dinamikusan töltöm be a dll-t, mert nincs az sdk-ban link library(illetve majd kártya nélkül is működnie kell a programnak), a C# programok is egy köztes dll-en(AdvMotAPI.dll) keresztül dinamikusan töltik be az ADVMOT.dll-t.
.NET reflectorral bele is néztem, pl.:
[DllImport("ADVMOT.dll", EntryPoint="Acm_DevOpen", CallingConvention=CallingConvention.StdCall)]
public static extern uint mAcm_DevOpen(uint DeviceNumber, ref IntPtr DeviceHandle);
[DllImport("ADVMOT.dll", EntryPoint="Acm_AxOpen", CallingConvention=CallingConvention.StdCall)]
public static extern uint mAcm_AxOpen(IntPtr DeviceHandle, ushort PhyAxis, ref IntPtr AxisHandle);
[DllImport("ADVMOT.dll", EntryPoint="Acm_AxHome", CallingConvention=CallingConvention.StdCall)]
public static extern uint mAcm_AxHome(IntPtr AxisHandle, uint homeMode, uint DirMode);
A fenti függvényeket C-ben így töltöm be:
typedef U32 (_stdcall * Acm_DevOpen_t)(U32 DeviceNumber, PHAND DeviceHandle);
typedef U32 (_stdcall * Acm_AxOpen_t)(HAND DeviceHandle, U16 PhyAxis, PHAND AxisHandle);
typedef U32 (_stdcall * Acm_AxHome_t)(HAND AxisHandle, U32 HomeMode, U32 DirMode);
Acm_DevOpen_t Acm_DevOpen;
Acm_AxOpen_t Acm_AxOpen;
Acm_AxHome_t Acm_AxHome;
Acm_DevOpen = (Acm_DevOpen_t)GetProcAddress(hInstLibrary, "Acm_DevOpen");
Acm_AxOpen = (Acm_AxOpen_t)GetProcAddress(hInstLibrary, "Acm_AxOpen");
Acm_AxHome = (Acm_AxHome_t)GetProcAddress(hInstLibrary,"Acm_AxHome");
A problémám a következő:
A fenti eljárással a hívások működnek C-ben is: relatív motor vezérlés, general purpose IO, stb.
Ami nem akar működni, csak C#-ból, az Acm_AxHome függvény.
Alábbi teljesen egyező C# és C móricka programok közül csak a C# hajlandó működni:
C#:
uint Result;
Result = Motion.mAcm_DevOpen(0x20000000, ref DeviceHandle);
Result = Motion.mAcm_AxOpen(DeviceHandle, (UInt16)0, ref AxisHandle);
Result = Motion.mAcm_AxHome(AxisHandle, 3, 0);
C:
U32 iResult;
iResult = Acm_DevOpen(0x20000000,&devHandle);
iResult = Acm_AxOpen(devHandle,0,&axHandle);
iResult = Acm_AxHome(axHandle,3,0);
Konstansok, visszatérési értékek, minden egyezik. Az Acm_AxHome nem ad hibakódot. Látszólag ugyanaz a két program, mégsem működik, csak C#-ból. Más hívásokkal nincs gond, csak ez az egy hívás rakoncátlankodik.
A C# köztes dll-ben a .NET reflector szerint nincs semmi extra inicializálás (constructor, statikus adattag), csak a függvényeket wrappeli.
Gondoltam arra, hogy a dinamikusan betöltött dll az aktuálisan futó szálról nem értesül a DllMain-ben és esetleg ezért valami inicializáció kimarad, emiatt próbáltam úgy is hogy a betöltés után új szálat indítok, de ez sem segített.
Vajon mire nem gondoltam még? Kifogytam az ötletekből. Adjatok még tippeket. Köszi.