Documentation
ScreenCaptureSDK Screen Sharing
Documentation
Demo APP
SDK Center
API Center
FAQ
Code Market
Console
Sign Up
Log In
中文站 English
  • Documentation
  • Screen Sharing
  • Best Practices
  • C# Calling C Interfaces Guide

C# Calling C Interfaces Guide

Last updated:2022-03-22 13:07

1 Import Dll

Put the C# project and the C Dll project under the same solution, so that you can realize the linkage debugging and enter the C Dll function directly from C#.

1.1 C/C++ Dll Export Method

/// \brief set log level and path
/// \param log_level log level
/// \param szLogDir log save path
/// \see ZegoScreenCaptureLogLevel
extern "C" __declspec(dllexport) void zego_screencapture_set_log_level(enum ZegoScreenCaptureLogLevel log_level, const char *szLogDir);

1.2 Import Dll and Methods in C#

Use the DLLImport method to call the unmanaged dynamic library.

//The path where DllImport dll is located
//The name of the EntryPoint function, you don’t need to write it
//SetLastError whether to keep the last error code of win32
//Expression of strings in CharSet dll
//CallingConvention function calling convention
[DllImport("ZegoScreenCapture.dll", EntryPoint = "zego_screencapture_set_log_level" SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void zego_screencapture_set_log_level(ZegoScreenCaptureLogLevel level, string path);

The function calling convention is explained as follows:

Calling Convention Description
Cdecl The caller cleans up the stack. This enables developers to call functions with varargs (such as Printf), making them available for methods that accept a variable number of parameters.
FastCall This calling convention is not supported.
StdCall The callee cleans up the stack. This is the default convention for using platform invoke to call unmanaged functions.
ThisCall The first parameter is the this pointer, which is stored in the register ECX. Other parameters are pushed onto the stack. This calling convention is used to call methods on classes exported from unmanaged DLLs.
Winapi This member is not actually a calling convention, but uses the default platform calling convention. For example, the default is StdCall on Windows. The default on CE.NET is Cdecl.

2 Type Conversion

The corresponding list of types in C/C++ and C# is as follows:

C/C++ C#
void* IntPtr
unsigned char Byte
short Int16
unsigned short UInt16
int Int32
int* IntPtr
unsigned int UInt32
long Int32
long long Int64
unsigned long UInt32
unsigned long long UInt64
char Char
char*, wchar_t*, const char*, const wchar_t* String
float Single
double Double
VARIANT Object
int&, int* output parameters ref int
Structure public struct Structure{}
Structure & ref Structure
Structure** out Structure
int i[10] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
int[] i
char buffer[10] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
string buffer

3 Parameter Passing

3.1 When Parameters are Structure Pointers

3.1.1 C Data Types and Function Prototypes

The following example demonstrates the structure and function prototype declared in the C interface.

struct ZegoScreenCaptureRect
{
    int left; ///< abscissa of upper left corner
    int top; ///< ordinate of the upper left corner
    int right; ///< abscissa of the lower right corner
    int bottom; ///< ordinate of the bottom right corner
};

/// \brief Get the coordinates of the specified window relative to the screen
/// \param handle Windows platform is the window handle, which can be obtained through zego_screencapture_enum_window_list
/// \param rect coordinate rectangle
/// \return When the window is invalid or the window is minimized and hidden, etc., it returns false when the coordinates are invalid, and returns true when the actual coordinates are obtained
SCREENCAPTURE_API bool zego_screencapture_get_window_rect(ZegoWindowHandle handle, struct ZegoScreenCaptureRect* rect);

3.1.2 C# Data Types and Methods

C# structures and function prototype corresponding to the C interface.

The C# structure layout needs to be consistent with the C structure.

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct ZegoScreenCaptureRect
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

[DllImport("ZegoScreenCapture.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool zego_screencapture_get_window_rect(IntPtr handle, ref ZegoScreenCaptureRect rect);

3.1.3 C# Call

The following example demonstrates how C# calls the C method. ref rect represents the incoming structure pointer.

ZegoScreenCaptureRect rect = new ZegoScreenCaptureRect();
ScreenCaptureManager.zego_screencapture_get_window_rect(m_windows[this.comboBoxWindow.SelectedIndex], ref rect);

3.2 When the Parameter is an Array Pointer

3.2.1 C Data Types and Function Prototypes

The following example demonstrates the C interface declaration method. handle_list is a pointer to an array of window handles.

/// \brief Specify windows, filter these windows when capturing the screen, and not display them on the screen
/// \param handle_list List of window handles to be filtered, only windows with layered attribute specified under win7 can be filtered
/// \param count the number of windows
/// \param add true to add the filter window, false to remove the filter window
/// \note 1. [window setSharingType:NSWindowSharingNone] filtering can be set under macOS.
/// 2. Only use zego_screencapture_set_target_window filter to take effect under macOS.
/// Filtering using zego_screencapture_set_target_screen under macOS does not take effect.
SCREENCAPTURE_API void zego_screencapture_set_excluded_windows(ZegoWindowHandle* handle_list,int count,bool add);

3.2.2 C# Data Types and Methods

The following example demonstrates how to import C interface in C#. IntPtr[] handle_list corresponds to ZegoWindowHandle* handle_list in C interface.

[DllImport("ZegoScreenCapture.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zego_screencapture_set_excluded_windows( IntPtr[] handle_list, int count, bool add);

3.2.3 C# Call

C# calls the C interface to set the filtered window list.

private void buttonRemoveExcludeWindow_Click(object sender, EventArgs e)
{
    //Remove the collection filter window
    IntPtr[] handle_list = new IntPtr[1];
    handle_list[0] = m_windows2[this.comboBoxWindow2.SelectedIndex];
    ScreenCaptureManager.zego_screencapture_set_excluded_windows(handle_list, 1, false);
}

3.3 When the Return Value is a Structure Array Pointer

3.3.1 C Data Types and Function Prototypes

The following example demonstrates the structure and function prototype declared in the C interface. The interface returns a pointer to the window information array.

struct ZegoScreenCaptureWindowItem
{
    ZegoWindowHandle handle; ///< window unique identifier
    char title[256]; ///< window title
    char image_path[256]; ///< The path where the window corresponds to the process
}

/// \brief Synchronously enumerate the window list, including the window title and the corresponding executable file name of the window
/// \param isIncludeIconic Whether to include the minimized window when enumerating. Non-zero means include the minimized window, otherwise it does not include the minimized window.
/// \param count the number of windows
/// \return The first address of the window list, need to pair to call zego_screencapture_free_window_list to release
/// \note You can get the window that needs to be shared through the thumbnail related interface
/// \see zego_screencapture_free_window_list
SCREENCAPTURE_API const struct ZegoScreenCaptureWindowItem* zego_screencapture_enum_window_list(int isIncludeIconic, uint32_t *count);

3.3.2 C# Data Types and Methods

C# declares the structure and function prototype corresponding to the C interface. The return value type is "IntPtr". When using it, you can use the pointer offset to get each item in the array.

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct ZegoScreenCaptureWindowItem
{
    public IntPtr handle;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string title;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string image_path;
};

[DllImport("ZegoScreenCapture.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr zego_screencapture_enum_window_list(int isIncludeIconic, ref uint count);

3.3.3 C# Call

C# calls the C interface to obtain the window information array, and uses the pointer offset windowsPtr + Marshal.SizeOf<ZegoScreenCaptureWindowItem>() * i to obtain the information of each window in the array.

private void buttonRefreshWindow_Click(object sender, EventArgs e)
{
    //Get the window list
    m_windows.Clear();
    m_windows2.Clear();
    this.comboBoxWindow.Items.Clear();
    this.comboBoxWindow2.Items.Clear();
    uint count = 0;
    //windowsPtr is a pointer to a structure array in C
    IntPtr windowsPtr = ScreenCaptureManager.zego_screencapture_enum_window_list(1, ref count);
    if (count> 0)
    {
        for (int i = 0; i <count; i++)
        {
            //Get the pointer of each item in the array by pointer offset
var Ptr = windowsPtr + Marshal.SizeOf<ZegoScreenCaptureWindowItem>() * i;
            //Convert the structure pointer in C to C# structure object
window = (ZegoScreenCaptureWindowItem)Marshal.PtrToStructure(Ptr, typeof(ZegoScreenCaptureWindowItem));

            //Because the string returned by the SDK is utf8 encoding, it needs to be converted to the default encoding of C#
            this.comboBoxWindow.Items.Add(Encoding.UTF8.GetString(Encoding.Default.GetBytes(window.title)));
            this.comboBoxWindow2.Items.Add(Encoding.UTF8.GetString(Encoding.Default.GetBytes(window.title)));

            m_windows.Add(window.handle);
            m_windows2.Add(window.handle);
        }
    }
    this.comboBoxWindow.SelectedIndex = 0;
    this.comboBoxWindow2.SelectedIndex = 0;
    //Call the C method to release the structure array
    ScreenCaptureManager.zego_screencapture_free_window_list(windowsPtr);
}

4 Callback Registration

4.1 C Callback Prototype and Registration Method

The C interface declares callback prototypes and methods for registering callbacks.

/// \brief Collection error callback
/// \param error error code
/// \param user_data user-defined data
/// \see ZegoScreenCaptureCaptureError
typedef void (*zego_screencapture_capture_error_notify_func)(enum ZegoScreenCaptureCaptureError error, void *data);

/// \brief Register collection exception notification
/// \param notify notification function
/// \param data User-defined data, transparently transmitted when callback
SCREENCAPTURE_API void zego_screencapture_reg_capture_error_notify(zego_screencapture_capture_error_notify_func notify, void *data);

4.2 C# Declarations and C Callback Delegate

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void zego_screencapture_capture_error_notify_func(ZegoScreenCaptureCaptureError error, IntPtr user_data);

4.3 C# Importing Registering Callback Method

[DllImport("ZegoScreenCapture.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zego_screencapture_reg_capture_error_notify(zego_screencapture_capture_error_notify_func notify, IntPtr data);

4.4 C# Register Callback Function

//Define the delegate object
ScreenCaptureManager.zego_screencapture_capture_error_notify_func m_zego_screencapture_capture_error_notify;

//Save the callback implementation method in the delegate object
m_zego_screencapture_capture_error_notify = new ScreenCaptureManager.zego_screencapture_capture_error_notify_func(zego_screencapture_capture_error_notify);

//The object must be registered here, the function name cannot be passed directly
ScreenCaptureManager.zego_screencapture_reg_capture_error_notify(m_zego_screencapture_capture_error_notify, IntPtr.Zero);

4.5 C# Implementation of Callback Function

public void zego_screencapture_capture_error_notify(ZegoScreenCaptureCaptureError error, IntPtr user_data)
{
    //Switch to C# thread
    DoInMainThread(() =>
    {
        showMsg("error");
    });
}

Because the execution of the callback is in the SDK thread, it is necessary to switch the execution of the callback to the C# thread to avoid multi-threaded access conflicts.

private delegate void DoInMainThreadDelegate();
private void DoInMainThread(DoInMainThreadDelegate func)
{
    this.Invoke(func);
}

5 Sample Code

Screen sharing C# sample source code includes screen sharing, window sharing, area sharing and other functions. It shows how to call the C interface in C# to realize screen capture and streaming. Developers can refer to its usage to implement their own business. Please refer to Sample Code.

Page Directory
  • Free trial
  • 提交工单
    咨询集成、功能及报价等问题
    电话咨询
    400 1006 604
    Get Consulting
    Scan Wechat QR code