Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
24 Views

Breaking a DLL into separate DLLs

Hello Community,

I currently have two Projects that are connected and work perfectly. There's a static library Project (exe) that calls a dynamic library project (dll). The DLL project consists of many Modules. I would like to break the DLL project into separate DLLs by compiling each module as an individual DLL.

Would you guide me where to find instructions on this? I am using Visual Studio to build the projects.

0 Kudos
22 Replies
Highlighted
Black Belt
24 Views

Do you really want to have

Do you really want to have each module as its own DLL? That seems unnecessarily complex. It may also be impossible if you have calls between the modules in both directions.

Open the VS solution containing your DLL. Select File > Add > New Project. Select Fortran DLL as the project type. In the Solution Explorer window, drag the module source file(s) from the current project to Source Files in the new project. Repeat this for each module.

Now open the executable project that, ideally, has as dependent projects the static library and DLL. Add all of the DLL projects you created to this one. Right click on the executable project, select Dependencies > Project Dependencies. Check the boxes for each DLL project.

This will most likely fail because your modules are not independent. But maybe you'll get lucky.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
24 Views

I know it may sound

I know it may sound unnecessary to break up the DLL but I'm going to experiment with separating one DLL.

I am following your instructions. The "main" DLL module is calling a subroutine that is calling another. I am trying to separate the latter subroutine as a DLL project. Then, it is called from the subroutine that is inside the "main" DLL Is that possible? Or does the separated subroutine have to be called directly from the "main" DLL? Or, does both DLLs have to be called by the static project?

Thanks!

0 Kudos
Highlighted
Black Belt
24 Views

Build a tree diagram of how

Build a tree diagram of how your calls go. If you have a routine in DLL B that is used only by DLL A, then DLL B needs to be a dependent of DLL A.

The static library doesn't really enter into this at all, as you never link it on its own. All that matters is that all of the DLL routines it references can be found when the EXE is linked.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Black Belt
24 Views

You said that in your current

You said that in your current single DLL you have several modules. Do those modules contain data objects? If so, breaking up the DLLs will entail doing quite a bit of additional coding to ensure that the new sets of DLLs have a consistent view of the data. If you do not do so, each DLL may have its own copies of the variables and any pair of DLLs that are supposed to share data may end up with separate and uncoordinated copies of the data.

0 Kudos
Highlighted
Beginner
24 Views

Thank you all for your

Thank you all for your comments.

I have tried to separate a single module into a separate DLL B from the main DLL A. In DLL A, there's a module that uses and calls DLL B . After creating a new project for DLL B and building the projects, I can't debug the code. I set DLL A to be dependent on DLL B.

In DLL B, I used these commands to export DLL B (this is a simplified example code):

subroutine DLL_B(x,y,z)
implicit none
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: DLL_B
!DEC$ ATTRIBUTES ALIAS:'DLL_B' :: DLL_B
!DEC$ ATTRIBUTES REFERENCE :: x,y,z
real(8) :: x,y,z
! the body of the code
end subroutine DLL_B

In the module that calls DLL B in the main DLL A, I added these lines:

module example

!DEC$ ATTRIBUTES DLLIMPORT,ALIAS: 'DLL_B' :: DLL_B

subroutine example(q)
implicit none
real(8)::q,x,y,z

call DLL_B(x,y,z)

end subroutine example
end module example

During the debug I get exception thrown error at the statement {call DLL_B(x,y,z)}. I am trying to figure out why. All the lib, exp and pdb files are output to the same debug directory. What am I missing? 

0 Kudos
Highlighted
Black Belt
24 Views

You didn't say STDCALL in the

You didn't say STDCALL in the caller.  If you used modules for everything, all the interfaces and calling method would get handled automatically.

That the program linked means your file locations are fine. I assume that the exception was either an access violation or a stack issue.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
24 Views

I added STDCALL to the caller

I added STDCALL to the caller as follows

module example

!DEC$ ATTRIBUTES DLLIMPORT,STDCALL,ALIAS: 'DLL_B' :: DLL_B

subroutine example(q)
implicit none
real(8)::q,x,y,z

call DLL_B(x,y,z)

end subroutine example
end module example

I still get the same error and yes it's access violation.

0 Kudos
Highlighted
Black Belt
24 Views

Since you're only showing us

Since you're only showing us pseudocode here, and not your actual code, it's hard for us to provide useful help. Do you recognize that simply saying STDCALL makes the arguments pass-by-value, and thus any attempt to assign to them in the subroutine will fail?

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
24 Views

Thanks, Steve!

Thanks, Steve!

It's working now. The reason was that there were a lot of pointer variables in the actual DLL_B code. I had to assign a fixed size to them. I also removed the STDCALL from the caller.

0 Kudos
Highlighted
Black Belt
24 Views

So these were POINTER dummy

So these were POINTER dummy arguments that you passed non-pointers to? That is supported in some contexts (not yours), but only when there is an explicit interface visible, which your psuedocode did not provide.

You should always have explicit interfaces visible. /warn:interface can help identify where these are required but not used, but I might be inclined nowadays to suggest /warn:external, which will give you errors for any call where an explicit interface or EXTERNAL attribute is not provided.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
24 Views

These were pointer dummies

These were pointer dummies that I passed pointer dummies to. Their size is determined inside DLL_B, and they're supposed to be allocated inside DLL_B as well. Would INTERFACE solve this issue?

0 Kudos
Highlighted
Black Belt
24 Views

Yes - if you have a POINTER

Yes - if you have a POINTER dummy, an explicit interface is required. See Doctor Fortran Gets Explicit – Again! -warn interface would likely complain to you about this, if you compiled things in the right order.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
24 Views

I have added a reference

I have added a reference block in the calling subroutine (DLL_A) where I added the pointer arrays and all the parameters that are called from DLL_B. I built the codes with warn:interfaces on and the solution was compiled without errors. Also, debugging is working and DLL_B is executed without errors.

However, some parameters from the caller subroutine (DLL_A) took some random values while I was debugging the code. Those parameters are not in the called subroutine (DLL_B), and they took those random values without being modified. Any idea of what to check in the code?

0 Kudos
Highlighted
24 Views

I tried code as above and got

I tried code as above and got an error code of 6530.

0 Kudos
Highlighted
Black Belt
24 Views

Please show the actual code

Please show the actual code you used and the actual error message. Few if any of us have memorized all of the error numbers, though if I have it right this one is "The array spec for this component must be of explicit shape and each bound must be an initialization expression." Since I see no arrays in the code posted in this thread, I am perplexed.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Black Belt
24 Views

Quote:kolber, Michael wrote:

kolber, Michael wrote:

I tried code as above and got an error code of 6530.

There is no complete body of code in this thread that you can designate as "code as above". There are many combinations and variations that could be tried, and that one such variation (with modifications by you, perhaps) produced an error message is not something that one would consider to be interesting or worth investigating.

0 Kudos
Highlighted
New Contributor I
24 Views

not something that one would

not something that one would consider to be interesting or worth investigating.

--------------------------------------------------------------------------------------------------------------------------------------------------

I thought something was worth investigating once, but then thought better and felt much better for my failure to perform and therefore perform at the level of the average human bean on the average day. or as my Dad used to say when I asked for a beer, leave your money on the frig. By the way, by the time you are old and tall enough to leave your money on the frig, you are old enough to have earned the money mowing lawns. 

0 Kudos
Highlighted
24 Views

>>...perform at the level of

>>...perform at the level of the average human bean...

Just how large is a human bean? As big as a Lima bean, green bean?

Jim Dempsey

0 Kudos
Highlighted
Black Belt
24 Views

Typo, intended "being",

Typo, intended "being", perhaps?

0 Kudos