рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╡рд┐рд░рд╛рд╕рдд рдХреЛрдб рдХреА рд▓рд╛рдЦреЛрдВ рдФрд░ рд▓рд╛рдЦреЛрдВ рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВред рд▓рд┐рдЧреЗрд╕реА рдореЗрдВ рдкрд╣рд▓рд╛ рд╕реНрдерд╛рди, рдмреЗрд╢рдХ, рдХреЛрдмреЛрд▓ рдХрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлреЛрд░рдЯреНрд░рд╛рди рдХреЛ рднреА рдмрд╣реБрдд рдХреБрдЫ рдорд┐рд▓рд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдореЙрдбреНрдпреВрд▓ред
рдмрд╣реБрдд рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдЙрдиреНрд╣реЛрдВрдиреЗ рдореБрдЭреЗ "рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдФрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕реБрдВрджрд░ рдХрд░рдиреЗ" рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рдПрдХ рдЫреЛрдЯрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо (1000 рд╕реЗ рдХрдо рд▓рд╛рдЗрдиреЗрдВ, рдПрдХ рдЪреМрдерд╛рдИ рд╕реЗ рдЕрдзрд┐рдХ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдФрд░ рд░рд┐рдХреНрдд рд▓рд╛рдЗрдиреЗрдВ) рд▓рд╛рдпрд╛ред рдпрджреНрдпрдкрд┐ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЫреЛрдЯрд╛ рд╣реИ, рдлрд┐рд░ рднреА рдореИрдВ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ - рдореЗрд░реЗ рдЪрд╛рдЪрд╛ рдзреНрдпрд╛рди рд╕реЗ рджреЛ рдФрд░ рдорд╣реАрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдпреЛрдЬрди рдХрд░реЗрдВрдЧреЗред
рдХреЛрдб рдХреЗ рдХрдИ рдЯреБрдХрдбрд╝реЛрдВ рдФрд░ рдПрдХ рдкрд╛рда рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдХрдЯ рдХреЗ рдиреАрдЪреЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВред
рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди
рдлреЛрд░рдЯреНрд░рд╛рди рдкрд░ рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реИ рдЬреЛ рдХреБрдЫ рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИред рдХрд╛рд░реНрдп: рдЗрд╕реЗ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдзрд┐рдорд╛рдирддрдГ - рдХрд╛рдо рдХреЗ рддрд░реНрдХ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдП рдмрд┐рдирд╛ - рдФрд░ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛, рд╕рд╛рде рд╣реА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рднреАред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪреАрдЬреЗрдВ рдХреИрд╕реЗ рдХрд░реЗрдВ:
- рдлреЛрд░рд▓реЗрди рдкрд░ рд╕рдВрдХрд▓рди;
- dll рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдХреА рдЧрдИ рд╡рд┐рдзрд┐рдпрд╛рдБ рдЦреЛрдЬреЗрдВ;
- рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВ:
- рдкрд░рдорд╛рдгреБ (
int
, double
); - рд╕реНрдЯреНрд░рд┐рдВрдЧ (
string
); - рдХреЙрд▓рдмреИрдХ (
Action<>
); - рд╕рд░рдгрд┐рдпрд╛рдБ (
double[]
);
- рдкреНрд░рдмрдВрдзрд┐рдд рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗ рдХреЙрд▓ рд╡рд┐рдзрд┐ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, C #)ред
рд╣рдо рд╕реА # рдореЗрдВ рдлреНрд░рдВрдЯ-рдПрдВрдб рдХрд░реЗрдВрдЧреЗ - рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдбрдмреНрд▓реНрдпреВрдкреАрдПрдл рдХреЗ рдХрд╛рд░рдг, рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред
рдкрд░реНрдпрд╛рд╡рд░рдг
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд░реНрдпрд╛рд╡рд░рдг рддреИрдпрд╛рд░ рдХрд░реЗрдВред
рдПрдХ рд╕рдВрдХрд▓рдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВрдиреЗ рдЬреАрд╕реАрд╕реА рдкреИрдХреЗрдЬ рд╕реЗ рдЧреИрдлрд░рд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ (рдЖрдк рдЗрд╕реЗ
рдпрд╣рд╛рдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ
рд╣реИрдВ )ред рдЧреНрдиреВ рдореЗрдХ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реИ (рдпрд╣
рдкрд╛рд╕ рдореЗрдВ рд╕реНрдерд┐рдд
рд╣реИ )ред рдЖрдк рд╕реНрд░реЛрдд рдХреЛрдб рд╕рдВрдкрд╛рджрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХреБрдЫ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ; рдореИрдВрдиреЗ
рдЧреНрд░рд╣рдг рдХреЛ Photran plugin рдХреЗ рд╕рд╛рде рд░рдЦрд╛ред
рдЧреНрд░рд╣рдг рдкрд░ рдкреНрд▓рдЧ-рдЗрди рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдореЗрдиреВ рдЖрдЗрдЯрдо "рд╕рд╣рд╛рдпрддрд╛" / "рдирдпрд╛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ ..." рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмреЗрд╕ рдЬреВрдиреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА (рдлрд╝рд┐рд▓реНрдЯрд░ рдореЗрдВ рдлреЛрдЯрд╛рди рджрд░реНрдЬ рдХрд░реЗрдВ) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдорд╛рдирдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╕рднреА рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдкрде рдХреЛ рдЧрд╛рд░реНрдЯрд░рди рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдФрд░ рдорд╛рдирдХ рдкрде рдореЗрдВ рдмрд╛рдпрдиреЗрд░рд┐рдЬрд╝ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреБрд░рд╛рдиреА рдлреЛрд░рдЯреНрд░рд╛рди рдмреЛрд▓реА рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рдЙрдиреНрд╣реЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ 6 рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреЗ рдЕрдирд┐рд╡рд╛рд░реНрдп рдЗрдВрдбреЗрдВрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд▓рд╛рдЗрдиреЗрдВ 72 рдкрд░рд┐рдЪрд┐рддреЛрдВ рддрдХ рд╕реАрдорд┐рдд рд╣реИрдВред рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд▓рд┐рдП рд╣реИ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рдЗрддрдирд╛ рдкреБрд░рд╛рдирд╛ рд╕реНрдХреВрд▓ рд╣реВрдВ рдФрд░ рдХрдЯреНрдЯрд░ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЬреЛ рд╣реИ рд╡рд╣ рдЙрд╕реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред
рд╕реА # рдХреЗ рд╕рд╛рде, рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ - рд╕реНрдЯреВрдбрд┐рдпреЛред рдореИрдВрдиреЗ VS2010 рдореЗрдВ рдХрд╛рдо рдХрд┐рдпрд╛ред
рдкрд╣рд▓рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо
рдлреЛрд░рдЯреНрд░рд╛рди
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЪрд▓реЛ рдПрдХ рд╕рд░рд▓ рдлреЛрд░рдЯреНрд░рд╛рди рдХрд╛рд░реНрдпрдХреНрд░рдо рдмрдирд╛рддреЗ рд╣реИрдВред
module test contains subroutine hello() print *, "Hello, world" end subroutine end module test program test_main use test call hello() end program
рд╣рдо рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рдЕрд▓рдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рд╣рдо рдпрд╣рд╛рдВ рдлреЛрд░рдЯреНрд░рд╛рди рдирд╣реАрдВ рд╕рд┐рдЦрд╛ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЙрди рдХреНрд╖рдгреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░реВрдВрдЧрд╛ рдЬреЛ рд╣рдо рдореБрдарднреЗрдбрд╝ рдХрд░реЗрдВрдЧреЗред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореЙрдбреНрдпреВрд▓ред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдк рдЙрдиреНрд╣реЗрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдореИрдВрдиреЗ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдЗрд╕рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдирд╛рдо рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реБрдПред рдореБрдХрд╛рдмрд▓рд╛ рдорд┐рд╢рди рдореЗрдВ, рд╕рдм рдХреБрдЫ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╡рд╣рд╛рдВ рдХреЛрдИ рдореЙрдбреНрдпреВрд▓ рдирд╣реАрдВ рд╣реИрдВред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдпрд╣ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рд░рд╛рд╕рдд рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреНрдпрд╛ рдЖрдпрд╛ рдерд╛ред
рджреВрд╕рд░реЗ, рдлреЛрд░рдЯреНрд░рд╛рди рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдРрд╕рд╛ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИрдВред рдЖрдк
endif
рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдк
end if
рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ
end if
ред рдЖрдк
do 1 i = 1, 10
рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдорд╛рдирд╡реАрдп рд░реВрдк рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ -
do 1 i = 1, 10
ред рддреЛ рдпрд╣ рд╕рд┐рд░реНрдл рдЧрд▓рддрд┐рдпреЛрдВ рдХрд╛ рднрдВрдбрд╛рд░ рд╣реИред рдЖрдзреЗ рдШрдВрдЯреЗ рдХреЗ рд▓рд┐рдП рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рдерд╛ рдХрд┐ рд▓рд╛рдЗрди рдХреНрдпреЛрдВ рд╣реИ
callback()
рддреНрд░реБрдЯрд┐ "
_back()
рд╡рд░реНрдг рдирд╣реАрдВ рдорд┐рд▓реА", рдЬрдм рддрдХ рдореБрдЭреЗ
_back()
рдЪрд▓ рдЧрдпрд╛ рдХрд┐ рдХреНрдпрд╛ рд▓рд┐рдЦрдирд╛ рд╣реИ
call callback()
рдЗрд╕рд▓рд┐рдП рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВред
рддреАрд╕рд░реЗ, рдПрдл 90 рдФрд░ рдПрдл 95 рдХреА рдмреЛрд▓рд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдВ, рдлрд┐рд░ рд╕реЗ, рд╕рдм рдХреБрдЫ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреНрдпрд╛ рдЖрдпрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдареАрдХ рд╣реИ, рд╡рд╛рдкрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВред рдпрд╣ рдпрд╛ рддреЛ рдЧреНрд░рд╣рдг рд╕реЗ рд╕рдВрдХрд▓рди рдХрд░рддрд╛ рд╣реИ (рдпрджрд┐ рдореЗрдХрдлрд╛рдЗрд▓ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ), рдпрд╛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ:
> gfortran -o bin\test.exe src\test.for
рд▓реЙрдиреНрдЪ рдХреА рдЧрдИ рдПрдХреНрд╕-рдлрд╛рдЗрд▓ рдХреЛ рдХ) рдХреЛ рдлреЛрд░рдЯреНрд░рд╛рди рд╕реЗ рд░рди-рдЯрд╛рдЗрдо рдбреАрдПрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдФрд░ рдмреА) рд╕реНрдЯреНрд░рд┐рдВрдЧ "рд╣реИрд▓реЛ, рд╡рд░реНрд▓реНрдб" рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред
рдПрдХ exe рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕реЗ рд░рдирдЯрд╛рдЗрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдВрдХрд▓рди рдХреЛ
-static
рд╕реНрд╡рд┐рдЪ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
> gfortran -static -o bin\test.exe src\test.for
Dll рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рдФрд░-рдХреБрдВрдЬреА рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
> gfortran -static -shared -o bin\test.dll src\test.for
рдЕрднреА рдХреЗ рд▓рд┐рдП, рд╣рдо рдлреЛрд░рдЯреНрд░рд╛рди рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕реА # рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред
C #
рдЪрд▓реЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╛рдирдХ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рддреЗ рд╣реИрдВред рддреБрд░рдВрдд рдПрдХ рдФрд░ рд╡рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ -
TestWrapper
рдФрд░ рдХреБрдЫ рдХреЛрдб рд▓рд┐рдЦреЗрдВ:
public class TestWrapper { [DllImport("test.dll", EntryPoint = "__test_MOD_hello", CallingConvention = CallingConvention.Cdecl)] public static extern void hello(); }
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдорд╛рдирдХ
dumpbin
рд╡реАрдПрд╕ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
> dumpbin /exports test.dll
рдпрд╣ рдЖрджреЗрд╢ рдПрдХ рд▓рдВрдмрд╛ рдбрдВрдк рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмреНрдпрд╛рдЬ рдХреА рд▓рд╛рдЗрдиреЗрдВ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:
3 2 000018CC __test_MOD_hello
рдЖрдк рдпрд╛ рддреЛ
grep
рд╕рд╛рде рдЦреЛрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдХрд┐рд╕реА рдлрд╛рдЗрд▓ рдореЗрдВ
dumpbin
рдЖрдЙрдЯрдкреБрдЯ рдбрдВрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЦреНрдп рдмрд╛рдд - рд╣рдордиреЗ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХрд╛ рдкреНрд░рддреАрдХрд╛рддреНрдордХ рдирд╛рдо рджреЗрдЦрд╛, рдЬрд┐рд╕реЗ рд╣рдорд╛рд░реЗ рдХреЙрд▓ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЖрдЧреЗ рдпрд╣ рдЖрд╕рд╛рди рд╣реИред рдореБрдЦреНрдп рдореЙрдбреНрдпреВрд▓ Program.cs рдореЗрдВ рд╣рдо рдПрдХ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ:
static void Main(string[] args) { TestWrapper.hello(); }
рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рдХреЗ, рдЖрдк рдлреЛрд░рдЯреНрд░рд╛рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣рдорд╛рд░реА рд▓рд╛рдЗрди "рд╣реИрд▓реЛ, рджреБрдирд┐рдпрд╛" рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдмреЗрд╢рдХ, рд╣рдореЗрдВ рдлреЛрд░рдЯреНрд░рд╛рди рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд test.dll рдХреЛ
bin/Debug
(рдпрд╛
bin/Release
)
bin/Release
рд░рдЦрдирд╛ рдирд╣реАрдВ рднреВрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдкрд░рдорд╛рдгреБ рдорд╛рдкрджрдВрдбреЛрдВ
рд▓реЗрдХрд┐рди рдпрд╣ рд╕рднреА рдирд┐рд░реНрдмрд╛рдз, рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ - рд╡рд╣рд╛рдВ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдХреБрдЫ рд╡рд╛рдкрд╕ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╣рдо рджреВрд╕рд░реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░реЗрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬреЛ рдкрд╣рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдирдВрдмрд░ 1 рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдкрд░рд┐рдгрд╛рдо рдкрд╛рд╕ рдХрд░рддреА рд╣реИред
рдлреЛрд░рдЯреНрд░рд╛рди
рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдкрдорд╛рдирдЬрдирдХ рд╣реИ:
subroutine add_one(inVal, retVal) integer, intent(in) :: inVal integer, intent(out) :: retVal retVal = inVal + 1 end subroutine
рдлреЛрд░рдЯреНрд░рд╛рди рдореЗрдВ, рдХреЙрд▓ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
integer :: inVal, retVal inVal = 10 call add_one(inVal, retVal) print *, inVal, ' + 1 equals ', retVal
рдЕрдм рд╣рдореЗрдВ рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЖрдк рдХрдВрд╕реЛрд▓ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдореЗрдлрд╛рдЗрд▓ рд╣реИред рдЗрд╕реЗ рд╡реНрдпрд╛рдкрд╛рд░ рд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
рдЪреВрдБрдХрд┐ рд╣рдо exe рдХрд░рддреЗ рд╣реИрдВ (рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП) рдФрд░ dll ("рдЙрддреНрдкрд╛рджрди рд╕рдВрд╕реНрдХрд░рдг" рдХреЗ рд▓рд┐рдП), рдпрд╣ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб рдореЗрдВ рдкрд╣рд▓реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ dll / exe рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЧреНрд░рд╣рдг рдореЗрдВ рдореЗрдХрдлрд╛рдЗрд▓ рдЦреЛрд▓реЗрдВ рдФрд░ рдЖрддреНрдорд╛ рдореЗрдВ рдХреБрдЫ рд▓рд┐рдЦреЗрдВ:
FORTRAN_COMPILER = gfortran all: src\test.for $(FORTRAN_COMPILER) -O2 \ -c -o obj\test.obj \ src\test.for $(FORTRAN_COMPILER) -static \ -o bin\test.exe \ obj\test.obj $(FORTRAN_COMPILER) -static -shared \ -o bin\test.dll \ obj\test.obj clean: del /Q bin\*.* obj\*.* *.mod
рдЕрдм рд╣рдо рдЧреНрд░рд╣рдг рд╕реЗ рдПрдХ рдмрдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдорд╛рдирд╡реАрдп рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдФрд░ рд╕рд╛рдл рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдорд╛рд░реНрдЧред
C #
рд▓рд╛рдЗрди рдореЗрдВ рдЕрдЧрд▓рд╛ C # рдореЗрдВ рд╣рдорд╛рд░реЗ рд╢реЗрд▓ рдХрд╛ рд╢реЛрдзрди рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ dll рд╕реЗ рдПрдХ рдФрд░ рд╡рд┐рдзрд┐ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ:
[DllImport("test.dll", EntryPoint = "__test_MOD_add_one", CallingConvention = CallingConvention.Cdecl)] public static extern void add_one(ref int i, out int r);
рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ
dumpbin
рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЪрд░ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдХреЙрд▓рд┐рдВрдЧ
cdecl
(рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ,
cdecl
) рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЪрд░ рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП
ref
рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЕрдЧрд░ рд╣рдо
ref
рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЬрдм рд╣рдо рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ AV рдорд┐рд▓рддрд╛ рд╣реИ: "рдЕрдирд╣реЗрд▓реНрджреА рдЕрдкрд╡рд╛рдж:
System.AccessViolationException
: рд╕рдВрд░рдХреНрд╖рд┐рдд рдореЗрдореЛрд░реА рдореЗрдВ рдкрдврд╝рдиреЗ рдпрд╛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдпрд╣ рдЕрдХреНрд╕рд░ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдФрд░ рд╕реНрдореГрддрд┐ рднреНрд░рд╖реНрдЯ рд╣реИред "
рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреБрдЫ рд▓рд┐рдЦреЗрдВ:
int inVal = 10; int outVal; TestWrapper.add_one(ref inVal, out outVal); Console.WriteLine("{0} add_one equals {1}", inVal, outVal);
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕рдм рдХреБрдЫ, рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдпрд╣ рдПрдХ "рд▓реЗрдХрд┐рди" рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдерд╛ - рдлрд┐рд░ рд╕реЗ, рдЖрдкрдХреЛ рдлреЛрд░рдЯреНрд░рд╛рди рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ
test.dll
рдХреЛ рдХреЙрдкреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдпрд╛рдВрддреНрд░рд┐рдХ рд╣реИ, рдЗрд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рд░рд╛рдЗрдЯ-рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, "рдЧреБрдг", "рдмрд┐рд▓реНрдб рдЗрд╡реЗрдВрдЯреНрд╕" рдЯреИрдм рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ, рдФрд░ рдирд┐рд░реНрдорд╛рдг рд╕реЗ рдкрд╣рд▓реЗ "рдХрдорд╛рдВрдб рдХрдорд╛рдВрдб рдСрдлрд╝ рдж рдЗрд╡реЗрдВрдЯ" рд╕реНрдкрд┐рд░рд┐рдЯ рдореЗрдВ рдХреБрдЫ рд▓рд┐рдЦреЗрдВред
make -C $(SolutionDir)..\Test.for clean make -C $(SolutionDir)..\Test.for all copy $(SolutionDir)..\Test.for\bin\test.dll $(TargetDir)\test.dll
рдмреЗрд╢рдХ, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд░рд╛рд╕реНрддреЗ рдЦреБрдж рд╣реА рдмрджрд▓рдиреЗ рдЪрд╛рд╣рд┐рдПред
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╕рдВрдХрд▓рди рдФрд░ рд▓реЙрдиреНрдЪ рдХреЗ рдмрд╛рдж, рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛ рдЧрдпрд╛, рддреЛ рд╣рдореЗрдВ рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдорд┐рд▓реЗрдЧрд╛ред
рдкрдВрдХреНрддрд┐рдпрд╛рдВ
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд▓рд┐рдЦрд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ dll рдореЙрдбреНрдпреВрд▓ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╣рдо рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЕрдХреНрд╕рд░ рдЖрдкрдХреЛ рдПрдХ рддрд░рд╣ рд╕реЗ рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдлреЗрдВрдХрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдПрдХ рдШрд╛рдд рд╣реИ рдЬреЛ рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрдпрд╛ - рдПрдиреНрдХреЛрдбрд┐рдВрдЧред рдЗрд╕рд▓рд┐рдП, рдореЗрд░реЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг рд▓реИрдЯрд┐рди рд╡рд░реНрдгрдорд╛рд▓рд╛ рдХреЗ рд▓рд┐рдП рджрд┐рдП рдЧрдП рд╣реИрдВред
рдлреЛрд░рдЯреНрд░рд╛рди
рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдХрдЯреНрдЯрд░ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЗ рд▓рд┐рдП):
subroutine progress(text, l) character*(l), intent(in) :: text integer, intent(in) :: l print *, 'progress: ', text end subroutine
рдЕрдЧрд░ рд╣рдордиреЗ рдбреАрдПрд▓рдЖрд░ рдФрд░ рдЕрдиреНрдп рдЗрдВрдЯрд░рдСрдкрд░реЗрдмрд┐рд▓рд┐рдЯреА рдХреЗ рдмрд┐рдирд╛ рдЗрдВрдЯреНрд░рд╛-рдлреЛрд░рдЯреНрд░рд╛рди рд╡рд┐рдзрд┐ рд▓рд┐рдЦреА, рддреЛ рд▓рдВрдмрд╛рдИ рдкреНрд░реЗрд╖рд┐рдд рдирд╣реАрдВ рдХреА рдЬрд╛ рд╕рдХрддреА рдереАред рдФрд░ рдЪреВрдВрдХрд┐ рд╣рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рджреЛ рдЪрд░, рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рдФрд░ рдЗрд╕рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдПрдХ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рднреА рд╕рд░рд▓ рд╣реИ:
character(50) :: strVal strVal = "hello, world" call progress(strVal, len(trim(strVal)))
len(trim())
рдХреЛ рдЕрдВрдд рдореЗрдВ рдЯреНрд░рд┐рдо рд╕реНрдкреЗрд╕ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ 50 рдЕрдХреНрд╖рд░ рдкреНрд░рддрд┐ рдкрдВрдХреНрддрд┐ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓ 12 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред
C #
рдЕрдм рдЖрдкрдХреЛ C # рд╕реЗ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╣рдо
TestWrapper
рдХреЛ рдЕрдВрддрд┐рдо рд░реВрдк
TestWrapper
:
[DllImport("test.dll", EntryPoint = "__test_MOD_progress", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern void progress([MarshalAs(UnmanagedType.LPStr)]string txt, ref int strl);
рдПрдХ рдФрд░ рдЖрдпрд╛рдд рд╡рд┐рдХрд▓реНрдк рдпрд╣рд╛рдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ -
CharSet
рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдирд┐рд░реНрджреЗрд╢ рднреА рд╕рдВрдХрд▓рдХ рдХреЛ рдЧреБрдЬрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ -
MarshalAs
ред
рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХреЙрд▓ рд╕рдВрджрд░реНрдн рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдХрд╛рд░рдг рдХреНрд░рд┐рдпрд╛рддреНрдордХрддрд╛ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде, рдЧрдВрднреАрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ (
ref
):
var str = "hello from c#"; var strLen = str.Length; TestWrapper.progress(str, ref strLen);
рдХреЙрд▓рдмреИрдХ
рд╣рдо рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдкрд░ рдЖрдП - рдХреЙрд▓рдмреИрдХ, рдпрд╛ рдПрдХ dll рдХреЗ рдЕрдВрджрд░ рдЧреБрдЬрд░рдиреЗ рд╡рд╛рд▓реЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред
рдлреЛрд░рдЯреНрд░рд╛рди
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддрд░реАрдХреЗ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред рдлреЛрд░рдЯреНрд░рд╛рди рдореЗрдВ, рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
subroutine run(fnc, times) integer, intent(in) :: times integer :: i character(20) :: str, temp, cs interface subroutine fnc(text, l) character(l), intent(in) :: text integer, intent(in) :: l end subroutine end interface temp = 'iter: ' do i = 1, times write(str, '(i10)') i call fnc(trim(temp)//trim(str), len(trim(temp)//trim(str))) end do end subroutine end module test
рдпрд╣рд╛рдВ рд╣рдореЗрдВ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ
interface
рдХреЗ рдирдП рдЕрдиреБрднрд╛рдЧ рдкрд░ рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдирд┐рд╖реНрдкрдХреНрд╖ рд░реВрдк рд╕реЗ рдХреНрд░рд┐рдпрд╛, рд▓реЗрдХрд┐рди, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреБрдЫ рднреА рдирдпрд╛ рдирд╣реАрдВ рд╣реИред
рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЖрд╣реНрд╡рд╛рди рдмрд┐рд▓рдХреБрд▓ рд╕рд╛рдорд╛рдиреНрдп рд╣реИ:
call run(progress, 10)
рдирддреАрдЬрддрди, рдкрд┐рдЫрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рд▓рд┐рдЦреА рдЧрдИ
progress
рд╡рд┐рдзрд┐ рдХреЛ 10 рдмрд╛рд░ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред
C #
C # рдкрд░ рдЬрд╛рдПрдВред рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рд╕рд╣реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде
TestWrapper
рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void Progress(string txt, ref int strl);
рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк
run
рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдХрд╣рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ:
[DllImport("test.dll", EntryPoint = "__test_MOD_run", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern void run(Progress w, ref int times);
рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ
dumpbin
рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИ; рдмрд╛рдХреА рднреА рд╣рдорд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИред
рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рднреА рд╕реАрдзрд╛ рд╣реИред рдЖрдк рдпрд╛ рддреЛ рджреЗрд╢реА рдлреЛрд░рдЯреНрд░рд╛рди рд╡рд┐рдзрд┐ (рдЬреИрд╕реЗ рдХрд┐
TestWrapper.progress
, рдЕрдВрддрд┐рдо рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рд╡рд░реНрдгрд┐рдд), рдпрд╛ рд╕реА # рд▓реИрдореНрдмреНрдбрд╛ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
int rpt = 5; TestWrapper.run(TestWrapper.progress, ref rpt); TestWrapper.run((string _txt, ref int _strl) => { var inner = _txt.Substring(0, _strl); Console.WriteLine("Hello from c#: {0}", inner); }, ref rpt);
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЙрдкрдХрд░рдг рд╣реИрдВ, рддрд╛рдХрд┐ рдХреИрдкреЗрд╕рд┐рдЯрд┐рд╡ рдСрдкрд░реЗрд╢рди рдХреА рдкреНрд░рдЧрддрд┐ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░ рдХреЙрд▓рдмреИрдХ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬрд┐рд╕реЗ рд╣рдо рдЕрднреА рддрдХ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рд╡рд╣ рд╣реИ рд╕рд░рдгрд┐рдпрд╛рдБ рдкрд╛рд╕ рдХрд░рдирд╛ред
рд╕рд░рдгрд┐рдпреЛрдВ
рдЙрдирдХреЗ рд╕рд╛рде рддрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдпрджрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд▓рд┐рдЦрдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рддреЛ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдкреЗрди рдХреЗ рд╕рд╛рде рдереЛрдбрд╝рд╛ рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдлреЛрд░рдЯреНрд░рд╛рди
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рд░рдгреА рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд▓рд┐рдЦреЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рд░рд┐рдЬрд░реНрд╡ рд╣реЛрдЧрд╛:
subroutine print_arr(str, strL, arr, arrL) integer, intent(in) :: strL, arrL character(strL), intent(in) :: str real*8, intent(in) :: arr(arrL) integer :: i print *, str do i = 1, arrL print *, i, " elem: ", arr(i) end do end subroutine
double
(рдпрд╛
real
рдбрдмрд▓ рдкрд░рд┐рд╢реБрджреНрдзрддрд╛) рдХреА рдПрдХ рд╕рд░рдгреА рдШреЛрд╖рдгрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рднреА рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдлреЛрд░рдЯреНрд░рд╛рди рд╕реЗ рдПрдХ рдХреЙрд▓ рднреА рдЖрдо рд╣реИ:
character(50) :: strVal real*8 :: arr(4) strVal = "hello, world" arr = (/1.0, 3.14159265, 2.718281828, 8.539734222/) call print_arr(strVal, len(trim(strVal)), arr, size(arr))
рдЖрдЙрдЯрдкреБрдЯ рдПрдХ рдореБрджреНрд░рд┐рдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдФрд░ рдПрдХ рд╕рд░рдгреА рд╣реИред
C #
TestWrapper
рдмрд╛рд░реЗ
TestWrapper
рдХреБрдЫ рдЦрд╛рд╕ рдирд╣реАрдВ рд╣реИ:
[DllImport("test.dll", EntryPoint = "__test_MOD_print_arr", CallingConvention = CallingConvention.Cdecl)] public static extern void print_arr(string titles, ref int titlesl, IntPtr values, ref int qnt);
рд▓реЗрдХрд┐рди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдЕрдВрджрд░ рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЕрд╕реЗрдВрдмрд▓реА
System.Runtime.InteropServices
рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
var s = "abcd"; var sLen = s.Length; var arr = new double[] { 1.01, 2.12, 3.23, 4.34 }; var arrLen = arr.Length; var size = Marshal.SizeOf(arr[0]) * arrLen; var pntr = Marshal.AllocHGlobal(size); Marshal.Copy(arr, 0, pntr, arr.Length); TestWrapper.print_arr(s, ref sLen, pntr, ref arrLen);
рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╕рд░рдгреА рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реВрдЪрдХ рдХреЛ рдлреЛрд░рдЯреНрд░рд╛рди рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЕрдВрджрд░ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрд░реНрдерд╛рдд рдкреНрд░рдмрдВрдзрд┐рдд рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдЕрдкреНрд░рдмрдВрдзрд┐рдд рдХреНрд╖реЗрддреНрд░ рдХреЗ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░, рддрджрдиреБрд╕рд╛рд░, рдЗрд╕рдореЗрдВ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ, рдпрд╣ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЧреЛрд▓реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ:
public static void PrintArr(string _titles, double[] _values) { var titlesLen = _titles.Length; var arrLen = _values.Length; var size = Marshal.SizeOf(_values[0]) * arrLen; var pntr = Marshal.AllocHGlobal(size); Marshal.Copy(_values, 0, pntr, _values.Length); TestWrapper.print_arr(_titles, ref titlesLen, pntr, ref arrLen); }
рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛
рд╕рднреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХрд╛ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб (рдФрд░ рдПрдХ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдмреЛрдирд╕)
рдмрд┐рдЯрдкрдХреЗрдЯ (рдПрдЪрдЬреА) рдкрд░ рднрдВрдбрд╛рд░ рдореЗрдВ рд╣реИрдВред рдпрджрд┐ рдХрд┐рд╕реА рдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдЬреЛрдбрд╝ рд╣реИ - рддреЛ рдЖрдкрдХрд╛ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рдкрд░рдВрдкрд░рд╛рдЧрдд рд░реВрдк рд╕реЗ, рдореИрдВ рд╣рд░ рдХрд┐рд╕реА рдХреЛ рдзрдиреНрдпрд╡рд╛рдж рджреЗрддрд╛ рд╣реВрдВ рдЬреЛ рдЕрдВрдд рддрдХ рдкрдврд╝рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдмрд╣реБрдд рдХреБрдЫ рдкрд╛рда рдирд┐рдХрд▓рд╛ред