[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Tim Barber

5/11/2007 7:08:00 PM

I am attempting to incorporate a 3rd party DLL that is unmanged into my
managed project. The problem as you might have guess is regarding getting a
callback to occur. The one big problem is that I don't have access to either
the code or the developer at this point hence my posting here.

I have been able to recreate the issue so I was hoping that someone could
tell me my issue. The code in the unmanaged DLL is basically this:

Header File:
#pragma once

typedef void (*__callbackroutine__)(BYTE byteOut);
typedef __callbackroutine__* CallbackRoutine;

extern "C"
{
void __declspec(dllexport) Initialize(char* port_name, CallbackRoutine
cb);
}


Source File:
#include "stdafx.h"
#include "PinPadDllEx.h"

CallbackRoutine CallBack;

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
BOOL ret_val = TRUE;

switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}

return ret_val;
}

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD
dwTime)
{
((void (*)(BYTE))CallBack)('A');
return;
}

void Initialize(char* port_name, CallbackRoutine cb)
{
CallBack = cb;

int ret_val = SetTimer(NULL, NULL, 1000, TimerProc);
return;
}

Source Code To Managed Container:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace TestPinPadDllEx
{
public delegate void KeyPressedCB(Byte key);

class Program
{
//public delegate void KeyPressedCB(Byte key);

[DllImport("PinPadDllEx.dll", EntryPoint = "Initialize",
ExactSpelling = false, CharSet = CharSet.Ansi, CallingConvention =
CallingConvention.Cdecl)]

public static void ProgramCB(Byte key)
{
System.Console.WriteLine("Key Press. Value: {0}", key);
return;
}

static void Main(string[] args)
{
string comm_s = "COM5";

KeyPressedCB cb = new KeyPressedCB(ProgramCB);

Initialize(comm_s, cb);

System.Threading.Thread.CurrentThread.Join();
System.Console.WriteLine("Process exiting.");
System.Console.ReadKey(true);
}
}

The "initialize" routine is called with good data. The issue is that the
TimerProc never gets called. It is not like I am getting an exception or GP.
Nothing happens. Obviously I am doing something wrong, but for the life of
me I can't figure it out.

By the way, I am using Visual Studio 2005 as my development system.

Many Thanks,

Tim


1 Answer

Tim Barber

5/14/2007 8:38:00 PM

0

The following was from the MSDN forum website. I am putting it here so
others will see the answer to my question.

SetTimer relies on WM_TIMER message to work correctly. The call to
Thread.Join will block the thread and preventing itself to process any
message. To fix this, a message loop needs to be provided:

while (true)
{
Application.DoEvents();
}

Note: The above loop if 'bad' in that it will never break out, but it
does work for testing purposes.

> I am attempting to incorporate a 3rd party DLL that is unmanged into my
> managed project. The problem as you might have guess is regarding getting a
> callback to occur. The one big problem is that I don't have access to either
> the code or the developer at this point hence my posting here.
>
> I have been able to recreate the issue so I was hoping that someone could
> tell me my issue. The code in the unmanaged DLL is basically this:
>
> Header File:
> #pragma once
>
> typedef void (*__callbackroutine__)(BYTE byteOut);
> typedef __callbackroutine__* CallbackRoutine;
>
> extern "C"
> {
> void __declspec(dllexport) Initialize(char* port_name, CallbackRoutine
> cb);
> }
>
>
> Source File:
> #include "stdafx.h"
> #include "PinPadDllEx.h"
>
> CallbackRoutine CallBack;
>
> BOOL APIENTRY DllMain( HMODULE hModule,
> DWORD ul_reason_for_call,
> LPVOID lpReserved)
> {
> BOOL ret_val = TRUE;
>
> switch (ul_reason_for_call)
> {
> case DLL_PROCESS_ATTACH:
> case DLL_THREAD_ATTACH:
> case DLL_THREAD_DETACH:
> case DLL_PROCESS_DETACH:
> break;
> }
>
> return ret_val;
> }
>
> VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD
> dwTime)
> {
> ((void (*)(BYTE))CallBack)('A');
> return;
> }
>
> void Initialize(char* port_name, CallbackRoutine cb)
> {
> CallBack = cb;
>
> int ret_val = SetTimer(NULL, NULL, 1000, TimerProc);
> return;
> }
>
> Source Code To Managed Container:
> using System;
> using System.Collections.Generic;
> using System.Runtime.InteropServices;
> using System.Text;
> using System.Threading;
>
> namespace TestPinPadDllEx
> {
> public delegate void KeyPressedCB(Byte key);
>
> class Program
> {
> //public delegate void KeyPressedCB(Byte key);
>
> [DllImport("PinPadDllEx.dll", EntryPoint = "Initialize",
> ExactSpelling = false, CharSet = CharSet.Ansi, CallingConvention =
> CallingConvention.Cdecl)]
>
> public static void ProgramCB(Byte key)
> {
> System.Console.WriteLine("Key Press. Value: {0}", key);
> return;
> }
>
> static void Main(string[] args)
> {
> string comm_s = "COM5";
>
> KeyPressedCB cb = new KeyPressedCB(ProgramCB);
>
> Initialize(comm_s, cb);
>
> System.Threading.Thread.CurrentThread.Join();
> System.Console.WriteLine("Process exiting.");
> System.Console.ReadKey(true);
> }
> }
>
> The "initialize" routine is called with good data. The issue is that the
> TimerProc never gets called. It is not like I am getting an exception or GP.
> Nothing happens. Obviously I am doing something wrong, but for the life of
> me I can't figure it out.
>
> By the way, I am using Visual Studio 2005 as my development system.
>
> Many Thanks,
>
> Tim
>
>