Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1707033
  • 博文数量: 607
  • 博客积分: 10031
  • 博客等级: 上将
  • 技术积分: 6633
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-30 17:41
文章分类

全部博文(607)

文章存档

2011年(2)

2010年(15)

2009年(58)

2008年(172)

2007年(211)

2006年(149)

我的朋友

分类: C/C++

2006-06-23 13:42:44

==============================================================================

Port from DOS/UNIX C code to WIN32 Easily

==============================================================================



Port from DOS/UNIX C code to WIN32 Easily






      Written late in the summer evening by Kerry D. Mathews II




In this article I will explain the quickest and easiest way

to take some of your some good C code and make a WIN32 application
from it.

How?

Easily, take your code or algorthms and put in into a 32bit DLL,
and use Visual Basic as your GUI.

Easy?

Of course. No Einsteins behind this keyboard.


A couple forward points I'd like to explain:



    A DLL is is nothing more than a dynamic linked library.

    It's pre-compiled code in a format that can be 'called' at runtime.

    Libraries are perfect places to store you near-famous algorthms, because

    the entry/exit points are uniform. That means you can use nearly any

    so-called visual front end, without having to modify the code again.

    Visual Basic is (imho) the best RAD tool ever made by

    the Microsoft Corporation. Visual Basic allows a developer make a

    prototype and take it to production status in a matter of hours.

    If you do not have any experience in WIN32 development, but have

    acquired quite a lot C/C++ expertise, then by all means give

    Visual Basic a try.

    The tools I used for this article were Borland C++ 4.52 and

    Microsoft Visual Basic 5.0, both very fine tools of the trade.






OK. Here's the project.





  • I need a GUI application that has an editable text field.



  • The application needs two buttons.



  • The first button takes the string from the box and increments the value
    of each character by one.



  • The second button takes the string from the box and decrements the value
    of each character by one.



  • The application needs to tell me, via a message box, when invalid input
    was entered into the text field.




Easy enough... let's make this interesting.



    We'll make the GUI, a VB app, have two buttons and a text field.

    When either button is pressed, it will make a call to a DLL.

    ..... Here's the part we put on our C hats.....

    The VB app will call a function from our DLL passing it two parameters,

    lets call them in_string and out_string, and the function will return

    a long value, result.

    The return value, called result, will tell us the completion status.

    If result equals one, the function succeded.

    The DLL will, of course have two functions that correspond to the

    VB calls. It will read in in_string, increment each char in the string,

    and the new string will be returned as out_string (if successful).

     




Let's start with the DLL.




As a matter of fact... Here's all the code.






/* ********** Oh My Gosh!  He's Pasting Code in the Channel !!
********* */

 
    #include

    #define EXPORT _export

    HINSTANCE   hInstance;

    char        szAppName[30];

    #pragma argsused

    BOOL WINAPI DllEntryPoint(HINSTANCE hInst,DWORD dwFunction,LPVOID lpNot)

    {

    if(dwFunction != DLL_PROCESS_ATTACH) return TRUE;

     hInstance = hInst;

     lstrcpy(szAppName, "convert");

     return TRUE;

    }

    #pragma argsused

    int WINAPI WEP (int bSystemExit){ return 1; }

    int WINAPI EXPORT InitconvertDLL(HINSTANCE hAppInstance){ return 1;
    }

    int WINAPI EXPORT TermconvertDLL(HINSTANCE hAppInstance){ return 1;
    }

    int WINAPI EXPORT CvtA2U( LPSTR in_str, LPSTR out_str )

    {

    int i = 0;

    int result = 0;

       i = strlen( in_str ); if( i < 1 ) return result;

       for( i = 0; i < (int)strlen( in_str ); i++ ) out_str[i]
    = in_str[i] + 1;

       out_str[i] = 0;   result = 1;

    return result;

    }

    int WINAPI EXPORT CvtU2A( LPSTR in_str, LPSTR out_str )

    {

    int i = 0;

    int result = 0;

       i = strlen( in_str ); if( i < 1 ) return result;

       for( i = 0; i < (int)strlen( in_str ); i++ ) out_str[i]
    = in_str[i] - 1;

       out_str[i] = 0;   result = 1;

    return result;

    }


/* ******* Oh My Gosh!  He's Done Pasting Code in the Channel !! *******
*/





 

Zounds! Not a lot of code!

And basically, no. A DLL doesnt need much more than that.

There are some basic mandatory DLL functions needed, namely:

    BOOL WINAPI DllEntryPoint(HINSTANCE,DWORD,LPVOID);

and
    int WINAPI WEP(int);

You must, of course, add your functions as well.

my functions are:

    int WINAPI EXPORT CvtA2U( LPSTR , LPSTR );
    int WINAPI EXPORT CvtU2A( LPSTR , LPSTR );

Do note, that even though they're declared as, return val int,

Visual Basic wants them declared as long. If i am wrong, /msg kuru.

LPSTR is win32 speak for a modifiable string.

There is a file called convert.def, it contains all of the functions

we want declared as exportable... that is callable from a win32 app.

The file looks like:

LIBRARY            
convert

DESCRIPTION        '32bit DLL'

EXPORTS            
CvtA2U

                   
CvtU2A

.. and thats it.

Making a win32 DLL is not hard at all. No Sir.

The location of the DLL is rather important. It should be located in
the

%PATH% directories or in the directory local to the calling executable.

The point I would like to stress, is that, in this example I am using
a

rather ineffective algorthm .. OK, call it lame. BUT.. You can easily

slip in your own code to do.. who knows what... FF4 conversions maybe.

Is it getting warm in here? Must be the light I'm letting in.

 


Now, On to the Visual Basic application.






Before you can call a DLL or any external library you must prototype
it

in a separate file. I called my header file (oops, C talk again) convert.bas
.

Convert.bas looks like:

    Attribute VB_Name = "Module1"

    Declare Function CvtA2U Lib "convert.dll" (ByVal instring As String,
    ByVal outstring As String) As Long
    Declare Function CvtU2A Lib "convert.dll" (ByVal instring As String,
    ByVal outstring As String) As Long

And that looks very much like our declarations in C... almost like cousins.

In fact.. I'll call it self explanatory.

The buttons we made in our VB app have code tied to the action (method)

of clicking on that particular button. Naturally, that is where we
would

place the actual call to our DLL.

Here's an example:

 

    Private Sub Command1_Click()
    Dim Results As Long
    Dim Return_str As String * 80
    Results = CvtA2U(Trim(Text1.Text), Return_str)
    If Results = 1 Then Text1.Text = Return_str Else MsgBox "Error"
    End Sub

As much as i hate to gloss over some aspects. You can clearly see

the call to our DLL. We've passed it two string parameters, and took
the

returning value in our variable 'Results'.

 

Well, I have to admit, it took me longer to write this article than
code

the examples. So now it's time to hide under my desk and take a nap.

I've included all the source code and makefiles to re-create the examples.

I hope this helps you to bridge your code to the world of WIN32. I
code for

a living too, so.. a little tidbit like this is can be a career saver.





 


Parting Notes:


 When developing your own VB apps that call your DLL, you may need
to add

 the line: chdir "c:\some_dir_that_holds_your_DLL" during
the

 VB development cycle. VB has a unelegant way of telling you it
couldn't find

 the DLL. Oh, and when you DLL is faulty... bad things can happen.

 Visual Basic Programmer's Guide to the Win32 API 
ISBN:  1-56276-287-7

 Although for VB 4.0, is a very good book. Hats off to Daniel
Appleman.

Items needed to make the 32bit DLL:



  • convert.mak (command line make file)



  • convert.ide (if using Borland C++ 4.52)



  • convert.c



  • convert.def


Items needed to make the Visual Basic 5.0 Application:


  • convert.bas



  • convert.frm



  • convert.vbp



  • convert.vbw


All source code should be found in

This page is Copyright © 1997 By . All Rights Reserved
阅读(715) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~