Integrating with legacy code

R

Russ

Hello. I have a very large business application written all in VC++
and MFC. Now I want to interface some of it to the web. I have
VS.NET2003 and have been studing walkthroughs and documentation and
trying some things. I wanted to build an XML web service that would
interface to my existing data and classes. But most of the examples
are for C#, which I do not know, and which can not understand the C++
header files needed to interface to my existing libraries.

But I did find the walkthrough called "Creating an XML Web Service
Using Managed Extensions for C++", and built it. It worked fine and I
made a couple of mods to test returning strings, etc. Finally, I
figured, now all I have to do is add my C++ header files and link with
the C++ DLL's for my system.

WRONG! The dang application can not even recognize such basic types
as WORD and UINT, never mind CString, CPtrList, etc etc etc. When I
try to include the necessary windows headers to make it recognize
those things it no longer will compile or link, and if I add what it
takes to make it link, then it won't run. (This is without calling a
single function in my old DLL.)

So I decided I had to start from scratch and rewrite everything doing
it the .NET way. I started by creating a single class and putting two
variables in it, a bool and a CString. No problem with the bool, but
it chokes on the CString. After some study, I tried including
cstringt.h. No good, the compiler does not even recognize CString as
a valid type. Next I tried including atlstr.h. It now says "warning
C4935: assembly access specifier modified from 'public'", and "error
C2872: 'IServiceProvider' : ambiguous symbol".

Next I studied some more and discovered the String class for managed
C++. AHA says I, that is what I need.

NOPE! Now it says "cannot declare a managed 'm_Fname' in an unmanaged
'CTestClass'".

If I can't even get a simple string class to work, how the heck am I
going to get collection classes and all my polymorphic classes etc, to
work!!!

It looks like .NET is only good if you are writing everything over
again from scratch. That is a hell of a huge learning curve and a
huge project even if I knew how. I thought .NET was supposed to make
it possible for all platforms and all operating systems to communicate
- easily. What am I missing, PLEASE!

Russ

PS: If you think it sounds like I am frustrated, you are right.
 
G

Gary Chang

Hi Russ,

Currently I am looking for somebody who could help you on it. We will reply
here with more information as soon as possible.
If you have any more concerns on it, please feel free to post here.


Thanks for your understanding!

Best regards,

Gary Chang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------
 
T

Tian Min Huang

Hi,

Thanks for your post. I reviewed your description carefully, and now I'd
like to share the following information with you:

1. To use CString class in your .NET managed C++ applicaiton, please
include atlstr.h header file and see if it works:
#include <atlstr.h>

2. Concerning the error message "cannot declare a managed 'm_Fname' in an
unmanaged 'CTestClass'", there is a workaround which uses the gcroot
template class. Note the use of vcclr.h required for the gcroot template
class. Please refer to the following article for detailed information and
sample:

__gc Pointers in Unmanaged Classes
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/ht
ml/vcManagedExtensionsSpec_16_3.asp

In addition, I'd like to recommend you an article below:

Converting Managed Extensions for C++ Projects from Pure Intermediate
Language to Mixed Mode
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/
vcconconvertingmanagedextensionsforcprojectsfrompureintermediatelanguagetomi
xedmode.asp

Hope this helps.

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
R

Russ

Min Hyang, thank you for your answer. However your answer focused on
just one small part of my problems. Just making the CString class
work is a minor part of the overall picture. Please try to understand
the bigger picture that I am asking about and address it in your
response.

That bigger picture is the whole issue of making legacy code work with
a .NET application. Fixing CString just leads to a host of additional
but similar problems. For instance, your fix of including atlstr.h I
had already tried. It compiles but then gives a lot of link errors
for common routines like memmove. Including the CRT library in the
project produces:
error LNK2020: unresolved token (0A00003C) _CrtDbgReport

But since it compiles ok, I thought I would try adding something else
that I need, CPtrLists. That causes a new round of problems. And so
it will go. Below is an example class that I will need to include in
order to make my legacy code interface to a .NET application:

class DllExport CPrinterOptionList : public CObList {
public:
DECLARE_SERIAL (CPrinterOptionList)

CPrinterOptionList () {}
CPrinterOptionList (const CPrinterOptionList& in) { *this = in; }
~CPrinterOptionList () { RemoveAll (); }

void RemoveAll (bool bDelete = true);

CPrinterOption *GetNext (POSITION &pos) const
{ return (CPrinterOption*) CObList::GetNext (pos); }

CPrinterOption *GetAt (POSITION &pos)
{ return (CPrinterOption*) CObList::GetAt (pos); }

CPrinterOption *GetHead ()
{ return (CPrinterOption*) CObList::GetHead (); }

void Delete (CPrinterOption* p);

const CPrinterOptionList& operator= (const CPrinterOptionList
&in);
bool operator== (const CPrinterOptionList& in) const;
bool operator!= (const CPrinterOptionList& in) const
{ return ! (*this == in); }
};

I don't expect this to be anything strange to you, but this is a very
small example of the kind of header file that will have to be included
in my application. How to do it?

To review. I have a large business app for which I have built up
custom libraries to access the data (which is not SQL data and not
available through ADO or OBDC, etc. in any way). I need to build
internet access to this data in the way of the .NET methods that
dynamically create web pages when a customer connects and requests
certain operations.

My approach was to be via the method described in the walkthrough
entitled "Creating an XML Web Service Using Managed Extensions for
C++".

How can I accomplish this? Where is the reference or article that
will allow me to get started in this direction?

Thank you! Russ
 
T

Tian Min Huang

Hello Russ,

Thanks for your response. I now share the following information with you:

1. I created a C++ managed project which includes atlstr.h, and then it
works properly with CString variables (both compile and execute).

2. When we use unmanaged code in C++ .NET application, we should include
corresponding header and library files. As in this case, I suggest that you
can keep your unmanaged C++ project and perform the following two steps in
order to add managed code to it:

step 1: Add the following code:
#using <mscorlib.dll>

If you are using VS .NET 2003, you can simple add reference to mscorlib.dll
in your project.

step 2: compile with /clr:

a. Open the project's Property Pages dialog box.
b. Click the Configuration Properties folder.
c. Click the General property page.
d. Modify the Use Managed Extensions property.

3. If the problem persists, could you post a simple project which is able
to reproduce the problem?

Hope this helps.

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
R

Russ

Ok Tian, if I understand you, you are saying that I can build some
managed code into my unmanaged DLL project and then access it from a
managed web server??? How does that work?

Meanwhile I found some information that helps and finally got my test
web service to compile. But there are problems.

First let me tell you what I have done.

Following the instructions in the article "Converting Managed
Extensions for C++ Projects from Pure Intermediate Language to Mixed
Mode", I changed my project settings as follows:

1. Link with /NOENTRY (was already set that way)
2. Removed nochkclr.obj as a linker input
3. Added msvcrt.lib as a linker input
4. Added __DllMainCRTStartup@12 to the Force Symbol References.

Also in stdafx.h, added includes for afx.h, afxwin.h, afxext.h,
afxdtctl.h, and afxcmn.h.

These changes allow me to compile and link and use such constructs as
CObject and CPtrList if they are created and used in the same test
project. But a strange thing happens. Every time I build the project
it indicates zero warnings and zero errors, but when I try to run the
project it tells me that the project is out of date and needs to be
rebuilt. If I build it again, it links only, but still tells me it is
out of date when I run it from VC++ (Ctrl + F5). In fact I can build
the project over and over and it relinks every time. This does not
happen when I change the project settings back to the original.

I cleaned/rebuilt, and then checked the date/time stamp of every item
in the debug folder and they were all the same (current time). I
waited until the next minute and hit "build solution" and the project
relinked.

However when I ignore the out of date warning and execute the program,
it works and all changes made in the last build are implemented
properly, so I have proceeded to try other things.

Once I had accomplished the above, I started to add code to use my MFC
Extention DLL. I had to make another change to the project settings,
changing the Configuration properties to "Use MFC in a Shared DLL".

This now works!!! I can create instances of classes in my library and
access them from within the web service, and display the results via
web methods.

I have now run smack into some security issues that I have not been
able to figure out, but I will start a new thread if/when I need help
with that.

But I would like some input from you about the "project out of date"
issue. That is very inconvenient and will cause problems when I get
ready to add projects like this to source control.

Thank you very much for your help. In the future if anyone else asks
about this issue, you could save some time by referring them to the
article "Converting Managed Extensions for C++ Projects from Pure
Intermediate Language to Mixed Mode".

Thanks again, Russ
 
T

Tian Min Huang

Hi Russ,

Thanks for your response.
into my unmanaged DLL project and then access it from a managed web
server??? How does that work?

As stated in my previous email, you can add reference to mscorlib.dll and
compile with /clr to build a mixed-mode assembly. I suggest that you can
create a Managed C++ XML Web Service, and then combine it to the mixed-mode
assembly.

Hope this helps.

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! -- www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Adding #include <atlstr.h> to a C++.NET managed class library appears to cause linking errors on /MTd.

What am I doing wrong?

Thank you,
 
G

Guest

FYI... I found a solution

#ifdef _DEBUG
#pragma comment(lib,"msvcrtd.lib")
#else
#pragma comment(lib,"msvcrt.lib")
#endif

in the stdafx.h file... =)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top