Silverfrost Forums

Welcome to our forums

Memory problems while executing function from C++ DLL

15 Mar 2013 10:10 #11778

Good evening,

I noticed a problem occuring when executing a function from a C++ DLL. Using the function from the DLL works perfectly with FTN95. The function loads a 3D model from a STL-File and does several modification to this model, which means a lot of memory is needed when the 3D models get larger.

When the stack size of the Fortran program is exceeded, the program throws an exception and stops executing. When I set the stack size higher, it can compute bigger 3D models, but this is not an option for the final program.

My question is: Is there any way to call a C++ Function without getting all variables saved into the stack, or is there a possibility to make the stack bigger dynamically?

15 Mar 2013 11:03 #11779

Its not clear what you mean here.

You can save stack space in your Fortran program by adding the SAVE declaration to each of your programs and subroutines. This cause local variables to be put in static memory.

Like this:

subroutine xxxx

   integer a, b, c
   real x, y, z
   save

   ! Do something

end subrouint
16 Mar 2013 9:00 #11786

How do you set the stack size higher (a SLINK command?) and why is this not an option for release?

16 Mar 2013 1:47 #11791

I'm not sure how to describe what I mean, lets just say the function I import from a DLL uses the whole stack memory. I set the stack memory higher with 'STACK 104857600' for 100 MB, which is still too small. If I set it any higher the program won't execute because of lacking RAM(according to the program). It's not an option for release, cause all the RAM would be reserved when starting the program, means if there is not enough RAM left according to the program, it won't execute.

A 3D model file with 1 MB needs more than 100 MB stack size during processing and if the stack is too small the program stops executing, but if I call the same DLL function from a C++ program it works fine.

17 Mar 2013 6:08 #11797

My recommendation is that you should consider a programming alternative that does not use 100mb of stack. The use of the stack for such large amounts is always going to cause problems. You could move temporary local variables from the stack by using ALLOCATE. This should be a more robust approach. If the variables are not temporary or local, why are they on the stack ?

John

17 Mar 2013 4:22 #11805

Quoted from JohnCampbell If the variables are not temporary or local, why are they on the stack ?

John

That's what I'm asking myself. Obviously all variables used in the C++ function from the DLL are considered temporary and therefore end up on the stack. Is there any way to tell FTN95 to not put variables of an external DLL function on the stack?

18 Mar 2013 6:09 #11811

Do you know what is going onto the stack ? I would have assumed they were temproary variables being created in the routine being called. Another possibility is they could also be array sections being genetated by the calling routine.

You need to identify what is being put onto the stack and consider an alternative.

John

18 Mar 2013 9:14 #11814

Quoted from cluosh When I set the stack size higher, it can compute bigger 3D models, but this is not an option for the final program.

Is the DLL routine recursive, or is it doing something as exotic as using alloca() to reserve space on stack?

If STL-file is in binary format, then you know the exact size of a model and could simply use malloc() to allocate a buffer for it.

18 Mar 2013 11:22 #11822

The DLL uses C++(new) instead of C(malloc) methods for reserving memory. Obviously variable memory reserved with 'new' ends up on the stack when calling the function through Fortran.

18 Mar 2013 11:37 #11823

I'm not sure of your knowledge in this area, when you say 'obviously'. Is that definately the case or are you saying in must be ?

I would recommend that you identify what is the source of the 100mb. C-Malloc and fortran-ALLOCATE do not use the stack, so if you can control this use you may be able to avoid the problem. I can confirm how to achieve this in Fortran, but I am not familiar with controlling this in C.

Is there any recursion involved ?

It should be a problem that can be solved.

John

18 Mar 2013 11:55 #11824

Yes I mean 'must be'. I can't prove the C++ memory allocation is done on the stack, but if malloc works this must be the case. I can't tell if there is any recursion involved for sure, but there probably is. I'm wondering tho if there is another way to solve the problem without having to use malloc, cause the whole library is huge and using C++ memory allocation, and it be quite an effort to rewrite everything to malloc.

19 Mar 2013 5:02 #11825

My understanding is that malloc derived arrays is not the problem, as these do not use the stack. I say this as in Fortran, ALLOCATE does not use the stack and I understand ALLOCATE is based on malloc.

Do you have access to the Fortran or C++ code to be able to modify either ? Have you been able to identify where the 100 mb is coming from? You have not yet indicated you have identified the source of this 100 mb. If you have, I'd be trying to specifically shift some of these arrays from the stack. Your options in Fortran are: Transfer the local array definitions to allocatable and allocate these arrays. ( large local arrays are the main source of stack usage) Alternatively if these arrays are being supplied, can you control their allocation elsewhere, such as using ALLOCATE or declaring them to be in COMMON or a MODULE; or using malloc if in C++.

Rather than try to fix the whole library, is there a single routine call that is generating this specific problem? If so can you change the program performance at this location.

I don't think I can help much more unless there is more information available.

John

19 Mar 2013 6:31 #11826

Quoted from cluosh The DLL uses C++(new) instead of C(malloc) methods for reserving memory. Obviously variable memory reserved with 'new' ends up on the stack when calling the function through Fortran.

No this isn't correct. How could the function in the DLL 'know' it is being called from Fortran. It can't. In C++ new allocates variables on the heap, not the stack.

If new (and malloc) used the stack, then then there wouldn't be any way of deleting variables, other than in reverse order of creation, and C++ allows variables to be created and deleted in any order.

My guess is that you problem is one of getting the interface to the call wrong in Fortran. This could cause corruption and filling up of the stack after multiple calls.

19 Mar 2013 4:46 #11833

Quoted from JohnCampbell

Do you have access to the Fortran or C++ code to be able to modify either ? Have you been able to identify where the 100 mb is coming from? You have not yet indicated you have identified the source of this 100 mb.

Yes I have access to the Fortran and the C++ Code, but it's hard to identify the source of the 100 mb. And there isn't a single C++ function containing all the code needed, a huge part of all functions of the library is used.

Quoted from davidb

My guess is that you problem is one of getting the interface to the call wrong in Fortran. This could cause corruption and filling up of the stack after multiple calls.

Definition of the function in C++:

DLL_HEADER void MESHSTLDEFAULT(const char* filename, const char* meshname, int fineness, bool additional_parameters)

Importing the function in Fortran:

c_external MESHSTLDEFAULT (STRING,STRING,VAL,VAL)

Compiling with:

ftn95 adds_meshing.f95 /ref nglib.dll

Linking with adding:

lo adds_meshing
lo nglib.dll

to the linker script. I've also tried to avoid including the DLL into the Fortran program, but writing an external C++ program and calling it with

i=START_PROCESS@('mesher.exe','m '//trim(filename)//' '//trim(meshname)//' 5 0')

The program executes perfectly, but the Fortran program crashes afterwards with a 'Floating point stack fault'-Exception.

19 Mar 2013 4:50 #11835

What does DLL_HEADER expand to?

19 Mar 2013 5:08 #11836

To

__declspec(dllexport)
19 Mar 2013 5:29 #11838

You may need to have extern 'C' in C++ in order to match c_external in FTN95.

19 Mar 2013 5:53 #11839

I'm sorry, yes, the prototypes of the C++ functions are defined with extern C.

Please login to reply.