Tim Barber
5/14/2007 8:38:00 PM
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
>
>