Каллер и вызываемая функция
Вызываемая функция
#include <stdio.h> #include <conio.h> #include<iostream> using namespace std; int fakt(int n).
Функция вызываемая после создания диалогового окна (MFC)
Добрый день Есть дилоговое приложение. Когда выполняются "долгие и тяжелые" операции, то форма.
При клики на кнопку много раз — вызываемая функция не успевает выполниться и происходит параллельное выполнение функций
При клики на кнопку много раз — вызываемая функция не успевает выполниться и происходит.
Сообщение от ДиманЪ
Я не профессиональный программист, но думаю что функция main() является основной и именно с нее начинается выполнение всей программы. И не зависимо сколько написано у вас функций, классов и прочего до оной (main) функции, все оно будет не выполнено, если только в главной функции не произойдет ее/его объявление.
Croessmah, да, Вы совершенно правы, спасибо за пример. Инициализация глобальной переменной происходит до входу в функцию main(). В свою защиту хочу сказать лишь только то, о чем писал выше, я не профессиональный программист, только учусь, и то — самостоятельно.
Но у меня к вам возник встречный вопрос, исходя из вашего примера. Почему при использовании функции int foo(), вы не возвращаете значение, понимаю, что компилятор gcc дает такую возможность, но все-же не является ли это ошибкой?
Вызов разделяемых библиотек из Simulink
Привет, Хабр!
Представляю вашему вниманию перевод статьи моего коллеги Михаила, посвященной методам вызова разделяемых библиотек в Simulink. Зачем она была создана вообще? Дело в том, что у многих компаний уже есть множество легаси-моделей, которые хотелось бы переиспользовать и нам часто задают вопросы «А как мне легаси интегрировать в Simulink? А если мое легаси в виде DLL?» Поэтому-то и была написана оригинальная статья.
Под катом рассматривается несколько способов по вызову разделяемых библиотек в Simulink.
Все изменения в код внесены с разрешения Михаила и сделаны, чтобы не перегружать статью.
В данной статье показано, как использовать функции из разделяемых библиотек в моделях Simulink.
Допустим, нам надо встроить в Simulink библиотеку exlib. Ее код содержится в исходниках exlib.c и exlib.h. Это очень простая библиотека, содержащая три функции:
void exlib_init(void) – открывает файл на запись.
void exlib_print(float data) – записывает данные в файл.
void exlib_term(void) – закрывает файл.
Сборка библиотеки
Для начала скомпилируем библиотеку.
Этот шаг не нужен, если библиотека предварительно скомпилирована и поставляется в виде двоичного файла. В этом случае сразу можно перейти к шагу 3, но надо помнить, что для работы с библиотекой нужно получить файл .dll (или .so для Linux) и соответствующий файл заголовка (.h) у поставщика библиотеки. Для Windows также понадобится файл .lib, который представляет собой не статическую библиотеку, а так называемую библиотеку импорта. Эта библиотека импорта потребуется для неявной линковки.
Сначала, будем использовать команду MATLAB mex, которая вызывает текущий активный компилятор хоста для компиляции общей библиотеки (exlib.dll в Windows и exlib.so в Linux). Важно убедиться, что сначала была выполнена команда
для выбора поддерживаемого компилятора.
Теперь используем mex для компиляции библиотеки:
Проверка скомпилированной библиотеки
После компиляции необходимо удостоверится в том, что полученная библиотека может быть подгружена и использована в MATLAB:
Теперь, когда мы удостоверились, что все работает, начнем работать с Simulink!
Вызов разделяемой библиотеки с помощью S-функций
S-функции позволяют использовать C код в Simulink. Этот подход позволяет пользователю разработать любой код на C, необходимый для загрузки библиотеки и вызова ее функций. Затем этот код компилируется в бинарный файл, который распознается Simulink и связывается с общей библиотекой. Этот двоичный файл называется S-функцией. В Simulink есть блок для вызова этой S-функции. Существует несколько подходов для создания S-функций в Simulink.
Использование Legacy Code Tool
Создадим S-функцию, скомпилируем и слинкуем ее:
Наконец создадим блок Simulink:
Написание S-функций вручную
Скомпилируем полученную S-функцию:
И запустим симуляцию:
Использование S-Function Builder
Еще один подход заключается в использовании блока S-Function Builder. Это специальный блок, который может рассматриваться как нечто среднее между Legacy Code Tool и написанными вручную S-функциями с точки зрения сложности. S-Function Builder предоставляет графический интерфейс, в котором описываются характеристики вашей S-функции, и S-функция создается автоматически.
При использовании S-Function Builder существуют некоторые ограничения и проблемы с производительностью. В настоящее время это считается устаревшим подходом к созданию S-функций. Рекомендуется использовать блок C function, который появился в релизе R2020а и обсуждается позже.
Вызов разделяемой библиотеки с помощью MATLAB Function
Данный подход имеет один недостаток – отсутствие хорошего способа вызвать функцию завершения при окончании симуляции (по сравнению с блоком MATLAB System).
Можно определить функцию завершения для модели, поставив exlib_term (); в настройках модели в категории Simulation Target -> Custom Code -> Terminate function.
ПРИМЕЧАНИЕ. Если в настройках модели установлен параметр «Import custom code», то требуется указать все зависимости кода на панели «Simulation Target» (вместо использования coder.cinclude и coder.updateBuildInfo). Если этот параметр не установлен, то можно объединить настройки из Simulation Target, coder.cinclude и coder.updateBuildInfo.
Другой способ — поддерживать зависимости, используя coder.cinclude и coder.updateBuildInfo, и вызывать exlib_term() по условию, как продемонстрировано в примере выше.
Запустим симуляцию:
Вызов разделяемой библиотеки из Stateflow
Если требуется использовать функции разделяемой библиотеки в диаграммах Stateflow, то эти функции следует вызывать напрямую из Stateflow. В документации Stateflow есть примеры, которые показывают, как это сделать.
Вызов внешней функции в Stateflow очень прост – требуется указать имя функции в диаграмме Stateflow: 
Дополнительно, необходимо настроить параметры модели, чтобы Stateflow знал, где искать эти внешние функции. В настройках Simulation Target -> Custom Code -> Libraries требуется ввести exlib.lib (или exlib.so в Linux). В Simulation Target -> Custom Code -> Header File требуется ввести #include «exlib.h». Также важно не забыть указать функцию завершения. В Simulation Target -> Custom Code -> Terminate function необходимо указать exlib_term() ;.
Запустим симуляцию:
Обратите внимание, что информация в этом разделе относится к диаграммам Stateflow, использующим язык действий C. В том случае, если диаграмма Stateflow использует язык действий MATLAB, то требуется использовать coder.ceval, как и для MATLAB Function.
Вызов разделяемой библиотеки с помощью блока MATLAB System
Вызов разделяемых библиотек с помощью блока C Caller
Блок C Caller позволяет вызывать функции C напрямую из Simulink. Более подробную информацию об этом блоке можно найти в документации.
Это относительно новый подход, который впервые появился в MATLAB R2018b. Его основная цель — сделать в Simulink вызовы функций и библиотек на C чрезвычайно простыми. Но у него есть ограничения, о которых вы можете прочитать в документации по этому блоку.
После того, как exlib.so/exlib.lib были добавлены в Simulation Target -> Libraries и #include «exlib.h» в Simulation Target -> Header в настройках модели, достаточно нажатия кнопки «Refresh custom code» в блоке C Caller, чтобы увидеть все функции, содержащиеся в библиотеке.
После выбора функции exlib_print, диалог спецификации портов заполняется автоматически:
И снова требуется добавить вызовы функций exlib_init и exlib_term, в Simulation Target. Также можно добавить пару других блоков C Caller для непосредственного вызова функций инициализации и завершения. Данные блоки C Caller потребуется поместить в подсистемы Initialize Function и Terminate Function. Также можно рассмотреть следующий пример из Stateflow: Schedule Subsystems to Execute at Specific Times
Запустим симуляцию:
Вызов разделяемых библиотек с помощью блока C Function
Новейшим дополнением к интеграции внешнего кода в Simulink является блок C Function. Он появился в R2020a.
Он напоминает блок C Caller с точки зрения простоты использования, но позволяет создавать код-обертку C вокруг импортируемых функций (таким образом, данный блок напоминает S-Function Builder). Но скорее всего основной сценарий использования блока C Function заключается не в вызове существующих функций C, а в написании небольших фрагментов кода на языке C, если такой код необходим в приложении. Например, может потребоваться доступ к аппаратным регистрам или встроенным функциям компилятора.
Не забудем добавить exlib.so/exlib.lib в настройки «Simulation Target -> Libraries» и #include «exlib.h» в настройки «Simulation Target -> Header file» в настройках модели.
После этого в настройках блока C Function надо добавить символ для входных данных с типом данных single и указать код вывода, запуска и завершения: 
Вызов разделяемых библиотек сгенерированных с помощью Embedded Coder
Одним из сценариев использования Embedded Coder является автоматическая генерация C-кода из модели Simulink и упаковка этого кода в разделяемую библиотеку. В документации также есть пример, который показывает, как автоматически генерировать разделяемую библиотеку и вызывать ее из внешнего приложения, написанного на C.
Обратите внимание, что если требуется просто запуск алгоритма или части алгоритма в виде C кода в той же модели Simulink, то лучше применить S-функции Simulink Coder или симуляции в режиме «ПО-в-контуре» (Software-in-the-Loop). Однако, если сгенерированная с помощью Embedded Coder разделяемая библиотека используется для полунатурного моделирования, то может потребоваться интегрировать эту же библиотеку в более крупную модель, используемую другими разработчиками и таким образом защитить свою интеллектуальную собственность.
Работа с разделяемой библиотекой, сгенерированная Embedded Coder, ничем не отличается от работы с разделяемой библиотекой, которая была использована в статье. Рассмотрим простую модель, которая имеет два входа и один выход:

После сборки модели мы получим файл .dll (.so в Linux), файл .lib (библиотека импорта для .dll) и файл .exp (файл экспорта для связи с .dll).
Сгенерированная разделяемая библиотека экспортирует следующие символы:
По умолчанию входы и выходы экспортируются как глобальные символы, а функции инициализации, шага и завершения следуют соглашению об именах моделей. При необходимости можно настроить прототипы функций, имена символов и прочее (обсуждение данных настроек выходит за рамки данной статьи). В этой модели прототип функции шага модели задан как Out1 = ex_step (In1, In2).
Для вызова этих функций нужно применить один из перечисленных выше методов. Например, можно использовать MATLAB Function (для простоты вызовем только функцию шага):
How to Find the Caller Method in C#

In this article, we will learn how to find the caller method in C#. We will also learn about scenarios in which this information could be useful and how to retrieve it.
What is the Caller Method?
In C#, we define a method that called the current method, also known as the “caller method”, as a method that invokes another method to carry out a specific task.
There are a variety of use cases where we might want to know what is the caller method:
- Debugging – If we’re trying to track down a bug in our code, knowing which method called the current method can help us narrow down the cause of the problem
- Logging – Including the name of the calling method can provide valuable context for a log message when logging information
- Performance profiling – If we are trying to optimize the performance of our application, knowing which methods are calling other methods can help us identify hot spots
Let’s now see how we can get this information.
How to Find the Caller Method
Let’s create a new console app in Visual Studio and define methods that we can inspect to see how to get caller method information:
We create a DoWork method which serves as a caller method since it calls the PrintCallerName method. In PrintCallerName , we gather information about its caller method and log it to the console.
To get information about the caller method, we create a StackTrace object to capture the stack trace information. Then, we use the GetFrames method to get an array of StackFrame objects that represent the method calls in the current execution stack. The second StackFrame object in the array represents the method that calls the current method. Lastly, we use the GetMethod method to retrieve a MethodBase object that holds information about the caller method’s signature.
Additionally, we want to log the name of the method which is being called, which is in our case PrintCallerName . To get this information, we use the MethodBase object, but this time we only need information about the current method. To get it, we use the GetCurrentMethod() method and store its name in the calledMethodName variable.
Now we have all information we need about the called and the caller methods and log them to the console.
Skipp Stack Creation
Previously we created a new StackTrace object to capture the stack trace information. This is useful when we need more detailed information about the call stack, such as file names, line numbers, and column numbers. Depending on our use case, and the information we want to capture, we can skip the StackTrace creation part to get the caller method:
To retrieve the name of the caller method, we again utilize a MethodBase object. This time we skip the process of creating a complete stack trace and instead immediately create a new StackFrame object with an offset of 1. This allows us to skip information about the current method and obtain details about the method that called it. Similar to the previous method, we store the name of the caller method in a variable called callerMethodName .
We perform the same steps as before to get the name of the called method.
In general, both methods are useful in different scenarios, and we should choose the one that best fits our requirements. If we are only interested in the calling method and its metadata, skipping stack creation can be more efficient. If we need more detailed information about the call stack, recreating it is a better approach.
Using CallerMemberName Attribute
One more approach to get the caller method name is to use the CallerMemberName attribute:
Lastly, we get the name of the called method name and log both of them to the console.
When working with attributes, in addition to CallerMemberName , there are other attributes that can provide more information about the caller method. For instance, if we want to know caller method line number we can use CallerLineNumber . Similarly, if we have an interest in the source path of the caller method, we can use CallerFilePath .
In general, all mentioned methods can be useful depending on the specific scenario, and we should choose the one that best fits our requirements. If we’re looking for a lightweight approach that only provides basic information about the calling method, using the CallerMemberName attribute may be the best choice. Since it doesn’t create a stack it is more performant than the first two methods. However, if we require more detailed information about the call stack, and are willing to trade some performance for this additional data, then creating a stack is likely the way to go.
Conclusion
In this article, we learned what it means when we say a method is a caller method. Also, we saw different situations in which we may need that information. Lastly, we saw what are some of the possible approaches for retrieving that information, and when to use them.
x86 Disassembly/Calling Conventions
Calling Conventions [ edit | edit source ]
Calling conventions are a standardized method for functions to be implemented and called by the machine. A calling convention specifies the method that a compiler sets up to access a subroutine. In theory, code from any compiler can be interfaced together, so long as the functions all have the same calling conventions. In practice however, this is not always the case.
Calling conventions specify how arguments are passed to a function, how return values are passed back out of a function, how the function is called, and how the function manages the stack and its stack frame. In short, the calling convention specifies how a function call in C or C++ is converted into assembly language. Needless to say, there are many ways for this translation to occur, which is why it’s so important to specify certain standard methods. If these standard conventions did not exist, it would be nearly impossible for programs created using different compilers to communicate and interact with one another.
There are three major calling conventions that are used with the C language on 32-bit x86 processors: STDCALL, CDECL, and FASTCALL. In addition, there is another calling convention typically used with C++: THISCALL. [1] There are other calling conventions as well, including PASCAL and FORTRAN conventions, among others.
Other processors, such as AMD64 processors (also called x86-64 processors), each have their own calling convention. [2] [3]
Notes on Terminology [ edit | edit source ]
There are a few terms that we are going to be using which are mostly common sense, but which are worthy of stating directly:
Passing arguments «passing arguments» is a way of saying that the calling function is writing data in the place where the called function will look for them. Arguments are passed before the call instruction is executed. Right-to-Left and Left-to-Right These describe the manner in which arguments are passed to the subroutine, in terms of the High-level code. For instance, the following C function call:
will generate the following code if passed Left-to-Right:
and will generate the following code if passed Right-to-Left:
Standard C Calling Conventions [ edit | edit source ]
The C language, by default, uses the CDECL calling convention, but most compilers allow the programmer to specify another convention via a specifier keyword. These keywords are not part of the ISO-ANSI C standard, so you should always check with your compiler documentation about implementation specifics.
If a calling convention other than CDECL is to be used, or if CDECL is not the default for your compiler, and you want to manually use it, you must specify the calling convention keyword in the function declaration itself, and in any prototypes for the function. This is important because both the calling function and the called function need to know the calling convention.
CDECL [ edit | edit source ]
In the CDECL calling convention the following holds:
- Arguments are passed on the stack in Right-to-Left order, and return values are passed in eax.
- The calling function cleans the stack. This allows CDECL functions to have variable-length argument lists (aka variadic functions). For this reason the number of arguments is not appended to the name of the function by the compiler, and the assembler and the linker are therefore unable to determine if an incorrect number of arguments is used.
Variadic functions usually have special entry code, generated by the va_start(), va_arg() C pseudo-functions.
Consider the following C instructions:
and the following function call:
These would produce the following assembly listings, respectively:
When translated to assembly code, CDECL functions are almost always prepended with an underscore (that’s why all previous examples have used «_» in the assembly code).
STDCALL [ edit | edit source ]
STDCALL, also known as «WINAPI» (and a few other names, depending on where you are reading it) is used almost exclusively by Microsoft as the standard calling convention for the Win32 API. Since STDCALL is strictly defined by Microsoft, all compilers that implement it do it the same way.
- STDCALL passes arguments right-to-left, and returns the value in eax. (The Microsoft documentation erroneously claimed that arguments are passed left-to-right, but this is not the case.)
- The called function cleans the stack, unlike CDECL. This means that STDCALL doesn’t allow variable-length argument lists.
Consider the following C function:
and the calling instruction:
These will produce the following respective assembly code fragments:
There are a few important points to note here:
- In the function body, the ret instruction has an (optional) argument that indicates how many bytes to pop off the stack when the function returns.
- STDCALL functions are name-decorated with a leading underscore, followed by an @, and then the number (in bytes) of arguments passed on the stack. This number will always be a multiple of 4, on a 32-bit aligned machine.
FASTCALL [ edit | edit source ]
The FASTCALL calling convention is not completely standard across all compilers, so it should be used with caution. In FASTCALL, the first 2 or 3 32-bit (or smaller) arguments are passed in registers, with the most commonly used registers being edx, eax, and ecx. Additional arguments, or arguments larger than 4-bytes are passed on the stack, often in Right-to-Left order (similar to CDECL). The calling function most frequently is responsible for cleaning the stack, if needed.
Because of the ambiguities, it is recommended that FASTCALL be used only in situations with 1, 2, or 3 32-bit arguments, where speed is essential.
The following C function:
and the following C function call:
Will produce the following assembly code fragments for the called, and the calling functions, respectively:
The name decoration for FASTCALL prepends an @ to the function name, and follows the function name with @x, where x is the number (in bytes) of arguments passed to the function.
Many compilers still produce a stack frame for FASTCALL functions, especially in situations where the FASTCALL function itself calls another subroutine. However, if a FASTCALL function doesn’t need a stack frame, optimizing compilers are free to omit it.
Commonly gcc and Windows FASTCALL convention pushes parameters one and two into ecx and edx, respectively, before pushing any remaining parameters onto the stack. Calling MyFunction3 using this standard would look like:
C++ Calling Convention [ edit | edit source ]
C++ requires that non-static methods of a class be called by an instance of the class. Therefore it uses its own standard calling convention to ensure that pointers to the object are passed to the function: THISCALL.
THISCALL [ edit | edit source ]
In THISCALL, the pointer to the class object is passed in ecx, the arguments are passed Right-to-Left on the stack, and the return value is passed in eax.
For instance, the following C++ instruction:
Would form the following asm code:
At least, it would look like the assembly code above if it weren’t for name mangling.
Name Mangling [ edit | edit source ]
Because of the complexities inherent in function overloading, C++ functions are heavily name-decorated to the point that people often refer to the process as «Name Mangling.» Unfortunately C++ compilers are free to do the name-mangling differently since the standard does not enforce a convention. Additionally, other issues such as exception handling are also not standardized.
Since every compiler does the name-mangling differently, this book will not spend too much time discussing the specifics of the algorithm. Notice that in many cases, it’s possible to determine which compiler created the executable by examining the specifics of the name-mangling format. We will not cover this topic in this much depth in this book, however.
Here are a few general remarks about THISCALL name-mangled functions:
- They are recognizable on sight because of their complexity when compared to CDECL, FASTCALL, and STDCALL function name decorations
- They sometimes include the name of that function’s class.
- They almost always include the number and type of the arguments, so that overloaded functions can be differentiated by the arguments passed to it.
Here is an example of a C++ class and function declaration:
And here is the resultant mangled name:
Extern «C» [ edit | edit source ]
In a C++ source file, functions placed in an extern «C» block are guaranteed not to be mangled. This is done frequently when libraries are written in C++, and the functions need to be exported without being mangled. Even though the program is written in C++ and compiled with a C++ compiler, some of the functions might therefore not be mangled and will use one of the ordinary C calling conventions (typically CDECL).
Note on Name Decorations [ edit | edit source ]
We’ve been discussing name decorations in this chapter, but the fact is that in pure disassembled code there typically are no names whatsoever, especially not names with fancy decorations. The assembly stage removes all these readable identifiers, and replaces them with the binary locations instead. Function names really only appear in two places:
- Listing files produced during compilation
- In export tables, if functions are exported
When disassembling raw machine code, there will be no function names and no name decorations to examine. For this reason, you will need to pay more attention to the way parameters are passed, the way the stack is cleaned, and other similar details.
While we haven’t covered optimizations yet, suffice it to say that optimizing compilers can even make a mess out of these details. Functions which are not exported do not necessarily need to maintain standard interfaces, and if it is determined that a particular function does not need to follow a standard convention, some of the details will be optimized away. In these cases, it can be difficult to determine what calling conventions were used (if any), and it is even difficult to determine where a function begins and ends. This book cannot account for all possibilities, so we try to show as much information as possible, with the knowledge that much of the information provided here will not be available in a true disassembly situation.
