|
|
To be able to advise you I need to know a couple of things
1.) Are we talking Fortran 77 or Fortran 90 code in the libraries and what complexity on exchange interface.
2.) How closely are you trying to mimic the functionality of the Delphi Application.
For point 1 there are some real complexities in linking Fortran 90 libraries to C++ as most of the advanced features are more closely related to Pascal than C++. Things that will give you nightmares are things like multi dimension arrays in column-major order, variant data fields require special conversions and any strings exchanges. So conceptually the linking of the libraries is easy but if the exchanges out of the Fortran libraries are complex the problem turns to a nightmare. So it's pretty much the same as linking them to Pascal but there are less consistency with datatypes used in the languages.
With point 2, I would first question why you want to use MFC and C++ for that matter? Delphi is much more structurally similar to C# this will give you the idea
Delphi vs. C# comparison | vsChart.com[^].
C++ is a level lower than Delphi, so what I am wondering here what is driving the want to bring the development onto C++. Don't get me wrong if you have a good C++ programmer they can easily convert it but the exact mimic of the framework well that is another story. I wrote the complete clean room copy of the Borlands objects unit that is in FreePascal (you will find me on the credits). I have also actually written a mimic of the whole Delphi 3 framework in C++ for an application I needed to exactly mirror and it took me just under 2 years. So is this being driven by a programmer wanting to make this choice or is it just a thought bubble.
I have similar reservations about MFC. It's still "current" and "used" but even Microsoft has now released it as free to use in VS2015 as it's commercial value is receding. Commercially most would select a different framework and to do that you start asking yourself do you need cloud access and the new technologies. If you don't need these you might select MFC but there are other choices.
In vino veritas
|
|
|
|
|
|
Your first link is bad.
I would not use system() to spawn a console app. Use ShellExecute() or CreateProcess() instead where you have (some) control over the ensuing window.
As far as WinMain() goes, see here.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
modified 9-Jun-16 9:12am.
|
|
|
|
|
It is impossible to guess what that code is supposed to be doing, or why it starts with a message box about a memory access error.
Please edit your question and explain exactly what you are trying to achieve. If this is just code from the internet that you do not understand then it would be better to contact the author.
|
|
|
|
|
Sometimes I just shake my head at answers offered ... anyhow moving on
Basically your definition of WinMain isn't correct it has parameters and a call directive, it will look like an overloaded function in that form
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
I haven't done this in ages but you had a console app and are trying to turn it to a windows app so there will be a project setting somewhere. To be honest the fastest way to do this will be to set the project up from scratch. Delete all the files in your directory except the source files and stuff you made. Then goto "new project" and select your directory but make sure you select Win32 Application not Win32 Console Application. On the next screen click on the "application settings" and tick the box "empty project". Ok all that and you get an empty project.
Now on the source files entry in solution explorer simply select "add existing item" and bring your source files in as you need.
With the right WinMain you are then good to compile and all should be fixed.
If that all gets too hard here is one I prepared earlier Skeleton Windows App project setup[^]
In vino veritas
modified 9-Jun-16 4:21am.
|
|
|
|
|
leon de boer wrote: Sometimes I just shake my head at answers offered I get much the same feeling with more and more of the questions posted here.
|
|
|
|
|
1.dev enviroment:VC++ 6.0
2.build program in 'release'
3.store 1000000 simple objects in CArray
4.run the program without debug
After running the code , it's about 85M memory cannot be release on my computer.
Can anyone explain and solve the problem for me? Thanks.
BTW:Because of the legency project code,my dev IDE is not allowed to update to the latest VisualStudio. So i have to solve the problem in VC 6.0 IDE.
#include "afxtempl.h"
long int g_cCount = 0;
long int g_dCount = 0;
class CMyTest
{
public:
CString m_str;
CMyTest()
{
m_str = "test string";
g_cCount++;
}
~CMyTest()
{
g_dCount++;
}
};
typedef CArray<CMyTest,CMyTest&> CArrayTest;
void Test()
{
g_cCount = 0;
g_dCount = 0;
CArrayTest testArray;
int count = 1000000;
for(int i =0;i < count; i++ )
{
CMyTest testObj;
testObj.m_str = "test string";
testArray.Add(testObj);
}
testArray.RemoveAll();
testArray.FreeExtra();
}
void CTestMemDlg::OnOK()
{
Test();
CString strInfo;
strInfo.Format("Object construction: %d destruction: %d \r\n",g_cCount,g_dCount);
AfxMessageBox("finish\r\n"+strInfo);
}
|
|
|
|
|
It's a long time since I did any MFC programming, but I suspect that the problem is the definition of CArrayTest. Try making this
typedef CArray<CMyTest,CMyTest> CArrayTest;
(no reference). This will cause every element to be copied into the array, but should work.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
I think you will find that RemoveAll will remove all the elements from the array but will not actually dispose them (i.e. call their destructors). Should be easy enough to test.
|
|
|
|
|
lostangels wrote:
CArrayTest testArray;
int count = 1000000;<br />
for(int i =0;i < count; i++ )
{
CMyTest testObj;
testObj.m_str = "test string";
testArray.Add(testObj);
}
What will happen if you change this code to
CArrayTest testArray;
int count = 1000000;<br />
testArray.SetSize(count, 100);
for(int i = 0; i < count; i++ )
{
CMyTest testObj;
testObj.m_str = "test string";
testArray.SetAt(i, testObj);
}
|
|
|
|
|
I am not convinced there is a leak ... Please explain this statement
After running the code , it's about 85M memory cannot be release on my computer
How exactly do you know it isn't released?
For example looking at the memory use in Task manager means nothing if that is all you are using. So has this statement got some actual tool basis?
If all you are doing is running task manager run the Test for me twice please one after another.
void CTestMemDlg::OnOK()
{
Test();
test();
CString strInfo;
strInfo.Format("Object construction: %d destruction: %d \r\n",g_cCount,g_dCount);
AfxMessageBox("finish\r\n"+strInfo);
}
If the memory use doesn't double to 170M you aren't leaking memory at all you just misunderstand what windows task manager is reporting.
In vino veritas
modified 6-Jun-16 9:34am.
|
|
|
|
|
How to track for char as input while doing addition for integers. If accidentally given char as input how to prevent it from performing addition calculation.
|
|
|
|
|
You can either
1.) Scan each character of the entry before doing anything with it, this is the generic form of a parser.
2.) Try converting it and if you get an error prompt, reloop and ask for entry again.
3.) Look for an error and if found exit program with error notification.
Which depends on what the source of the number is and what your goals with your program are. For example if the source of the number is a file not much use prompting and asking for re-entry ... files can't do anything about it
So the question comes down as, in the program you are writing what do you think it should do? What is the most elegant and most useful?
In vino veritas
modified 5-Jun-16 3:13am.
|
|
|
|
|
Can anyone explain me what is the difference in determination value?
double a = 0.0;
double a = .0;
double a = 0.;
|
|
|
|
|
No difference, they all represent the value 0.00, they are just different ways of writing it in source code. You could easily have found this out by writing a small program and stepping through it with your debugger.
|
|
|
|
|
Does exist any document or standard how correct use it forms?
|
|
|
|
|
|
Sorry, what do you mean by 'correct'? All the examples are correct, in that they declare the value as zero.
|
|
|
|
|
Hi,
I have a Base Class Header File as follows,
class MyClass,typedef void (MyClass::*PFN_DO_SOMETHING)(void* pData);
class MyClass{
PFN_DO_SOMETHING m_pfnDoSomething;
void Act(void* pData);
}
void MyClass::Act(void* pData){
m_pfnDoSomething(pData);
}
Needless to say, 'pfnDoSomething' has been initialised elsewere. I boiled the question down to the essentials, the correct CPP syntax for calling a member function from a pointer to it.
I get a Compiler error stating that 'pfnDoSomething' does not resolve to a function call.
What is the correct syntax for calling this function.
regards
Bram van Kampen
modified 2-Jun-16 4:00am.
|
|
|
|
|
The solution:
class MyClass{
typedef void (*MyClass::PFN_DO_SOMETHING)(void* pData);
PFN_DO_SOMETHING m_pfnDoSomething;
void Act(void* pData);
};
void MyClass::Act(void* pData){
m_pfnDoSomething(pData);
}
Your errors:
- The asterisk in the
typedef is at the wrong place. - Place the
typedef inside the class to avoid the forward declaration which would not work here with the correct typedef . - The function member name is
m_pfnDoSomething (not pfnDoSomething ).
Note also that there is no need to use the class prefix with the typedef . You may also use:
typedef void (*PFN_DO_SOMETHING)(void* pData);
|
|
|
|
|
I've always had difficulty with this, but if memory serves, function pointers in classes are required to be declared static .
[edit]
Memory does not serve.
[/edit]
modified 2-Jun-16 3:16am.
|
|
|
|
|
As per Jochen's answer but I would also add a guard against your forgetting to set the pointer checking it's not NULL. The typecast and advance definition is also unnecessary unless you actually need the type for something, the pointer will be checked for match when you attempt to set it with or without the typecast.
void MyClass::Act(void* pData){
if (m_pfnDoSomething) m_pfnDoSomething(pData);
}
Here is a minimalist function ptr .. no need for forward delaration, typedef or even a name of field. All you need is the * dereference before the function ptr name it knows what you are doing from that and really all it needs is what the function looks like so when you try to set it, that it checks for match.
class MyClass{
void(*MyClass::m_pfnDoSomething)(void*);
void MyClass::Act(void* pData){
if (m_pfnDoSomething) m_pfnDoSomething(pData);
}
};
Finally especially since your in a class I would suggest you don't pass in the void* data pointer but look at other options to typecast or marshal the data in a way that is a little safer.
In vino veritas
modified 4-Jun-16 11:36am.
|
|
|
|
|
How to generate XML file dynamically using C on Linux platform?
|
|
|
|
|
The quick and dirty way it is just matter of printf (and the gcc compiler).
e.g.
#include <stdio.h>
int main(int argc, char * argv[])
{
if (argc != 2) return -1;
printf("<html>\n<head></head>\n<body>\n<p>hello %s, welcome!</p></body></html>", argv[1]);
return 0;
}
|
|
|
|