# Do not edit this file; it was automatically generated.

import ctypes
import logging
import platform
import warnings
from typing import Optional

import numpy
from typing import List

from nidaqmx._base_interpreter import BaseEventHandler, BaseInterpreter
from nidaqmx._lib import lib_importer, ctypes_byte_str, c_bool32, wrapped_ndpointer
from nidaqmx.error_codes import DAQmxErrors, DAQmxWarnings
from nidaqmx.errors import DaqError, DaqFunctionNotSupportedError, DaqReadError, DaqWarning, DaqWriteError
from nidaqmx._lib_time import AbsoluteTime


_logger = logging.getLogger(__name__)
_was_runtime_environment_set = None


class LibraryEventHandler(BaseEventHandler):
    """Manage the lifetime of a ctypes callback method pointer.

    If DAQmx invokes a callback method pointer that has been garbage collected, the Python
    interpreter will crash.
    """
    __slots__ = ["_callback_method_ptr"]

    def __init__(self, callback_method_ptr: object) -> None:
        self._callback_method_ptr = callback_method_ptr

    def close(self) -> None:
        self._callback_method_ptr = None


class LibraryInterpreter(BaseInterpreter):
    """
    Library C<->Python interpreter.
    This class is responsible for interpreting the Library's C API.

    """
    # Do not add per-task state to the interpreter class.
    __slots__ = ()

    def __init__(self):
        global _was_runtime_environment_set 
        if _was_runtime_environment_set is None:
            try:
                runtime_env = platform.python_implementation()
                version = platform.python_version()
                self.set_runtime_environment(
                    runtime_env,
                    version,
                    '',
                    ''
                )
            except DaqFunctionNotSupportedError:
                pass
            finally:
                _was_runtime_environment_set = True


    def add_cdaq_sync_connection(self, port_list):
        cfunc = lib_importer.windll.DAQmxAddCDAQSyncConnection
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            port_list)
        self.check_for_error(error_code)

    def add_global_chans_to_task(self, task, channel_names):
        cfunc = lib_importer.windll.DAQmxAddGlobalChansToTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str]

        error_code = cfunc(
            task, channel_names)
        self.check_for_error(error_code)

    def add_network_device(
            self, ip_address, device_name, attempt_reservation, timeout):
        cfunc = lib_importer.windll.DAQmxAddNetworkDevice
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str, c_bool32,
                        ctypes.c_double, ctypes.c_char_p, ctypes.c_uint]

        temp_size = 0
        while True:
            device_name_out = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                ip_address, device_name, attempt_reservation, timeout,
                device_name_out, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return device_name_out.value.decode(lib_importer.encoding)

    def are_configured_cdaq_sync_ports_disconnected(
            self, chassis_devices_ports, timeout):
        disconnected_ports_exist = c_bool32()

        cfunc = lib_importer.windll.DAQmxAreConfiguredCDAQSyncPortsDisconnected
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_double,
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            chassis_devices_ports, timeout,
            ctypes.byref(disconnected_ports_exist))
        self.check_for_error(error_code)
        return disconnected_ports_exist.value

    def auto_configure_cdaq_sync_connections(
            self, chassis_devices_ports, timeout):
        cfunc = lib_importer.windll.DAQmxAutoConfigureCDAQSyncConnections
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_double]

        error_code = cfunc(
            chassis_devices_ports, timeout)
        self.check_for_error(error_code)

    def calculate_reverse_poly_coeff(
            self, forward_coeffs, min_val_x, max_val_x, num_points_to_compute,
            reverse_poly_order):
        size = len(forward_coeffs) if reverse_poly_order < 0 else reverse_poly_order + 1
        reverse_coeffs = numpy.zeros(size, dtype=numpy.float64)

        cfunc = lib_importer.windll.DAQmxCalculateReversePolyCoeff
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W'))]

        error_code = cfunc(
            forward_coeffs, len(forward_coeffs), min_val_x, max_val_x,
            num_points_to_compute, reverse_poly_order, reverse_coeffs)
        self.check_for_error(error_code)
        return reverse_coeffs.tolist()

    def cfg_anlg_edge_ref_trig(
            self, task, trigger_source, pretrigger_samples, trigger_slope,
            trigger_level):
        cfunc = lib_importer.windll.DAQmxCfgAnlgEdgeRefTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_double, ctypes.c_uint]

        error_code = cfunc(
            task, trigger_source, trigger_slope, trigger_level,
            pretrigger_samples)
        self.check_for_error(error_code)

    def cfg_anlg_edge_start_trig(
            self, task, trigger_source, trigger_slope, trigger_level):
        cfunc = lib_importer.windll.DAQmxCfgAnlgEdgeStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_double]

        error_code = cfunc(
            task, trigger_source, trigger_slope, trigger_level)
        self.check_for_error(error_code)

    def cfg_anlg_multi_edge_ref_trig(
            self, task, trigger_sources, pretrigger_samples,
            trigger_slope_array, trigger_level_array):
        cfunc = lib_importer.windll.DAQmxCfgAnlgMultiEdgeRefTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint32, ctypes.c_uint]

        error_code = cfunc(
            task, trigger_sources, trigger_slope_array, trigger_level_array,
            pretrigger_samples, len(trigger_level_array))
        self.check_for_error(error_code)

    def cfg_anlg_multi_edge_start_trig(
            self, task, trigger_sources, trigger_slope_array,
            trigger_level_array):
        cfunc = lib_importer.windll.DAQmxCfgAnlgMultiEdgeStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint]

        error_code = cfunc(
            task, trigger_sources, trigger_slope_array, trigger_level_array,
            len(trigger_level_array))
        self.check_for_error(error_code)

    def cfg_anlg_window_ref_trig(
            self, task, trigger_source, window_top, window_bottom,
            pretrigger_samples, trigger_when):
        cfunc = lib_importer.windll.DAQmxCfgAnlgWindowRefTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_double, ctypes.c_double,
                        ctypes.c_uint]

        error_code = cfunc(
            task, trigger_source, trigger_when, window_top, window_bottom,
            pretrigger_samples)
        self.check_for_error(error_code)

    def cfg_anlg_window_start_trig(
            self, task, window_top, window_bottom, trigger_source,
            trigger_when):
        cfunc = lib_importer.windll.DAQmxCfgAnlgWindowStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, trigger_source, trigger_when, window_top, window_bottom)
        self.check_for_error(error_code)

    def cfg_burst_handshaking_timing_export_clock(
            self, task, sample_clk_rate, sample_clk_outp_term, sample_mode,
            samps_per_chan, sample_clk_pulse_polarity, pause_when,
            ready_event_active_level):
        cfunc = lib_importer.windll.DAQmxCfgBurstHandshakingTimingExportClock
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_ulonglong, ctypes.c_double, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int]

        error_code = cfunc(
            task, sample_mode, samps_per_chan, sample_clk_rate,
            sample_clk_outp_term, sample_clk_pulse_polarity, pause_when,
            ready_event_active_level)
        self.check_for_error(error_code)

    def cfg_burst_handshaking_timing_import_clock(
            self, task, sample_clk_rate, sample_clk_src, sample_mode,
            samps_per_chan, sample_clk_active_edge, pause_when,
            ready_event_active_level):
        cfunc = lib_importer.windll.DAQmxCfgBurstHandshakingTimingImportClock
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_ulonglong, ctypes.c_double, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int]

        error_code = cfunc(
            task, sample_mode, samps_per_chan, sample_clk_rate,
            sample_clk_src, sample_clk_active_edge, pause_when,
            ready_event_active_level)
        self.check_for_error(error_code)

    def cfg_change_detection_timing(
            self, task, rising_edge_chan, falling_edge_chan, sample_mode,
            samps_per_chan):
        cfunc = lib_importer.windll.DAQmxCfgChangeDetectionTiming
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_ulonglong]

        error_code = cfunc(
            task, rising_edge_chan, falling_edge_chan, sample_mode,
            samps_per_chan)
        self.check_for_error(error_code)

    def cfg_dig_edge_ref_trig(
            self, task, trigger_source, pretrigger_samples, trigger_edge):
        cfunc = lib_importer.windll.DAQmxCfgDigEdgeRefTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int, ctypes.c_uint]

        error_code = cfunc(
            task, trigger_source, trigger_edge, pretrigger_samples)
        self.check_for_error(error_code)

    def cfg_dig_edge_start_trig(self, task, trigger_source, trigger_edge):
        cfunc = lib_importer.windll.DAQmxCfgDigEdgeStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int]

        error_code = cfunc(
            task, trigger_source, trigger_edge)
        self.check_for_error(error_code)

    def cfg_dig_pattern_ref_trig(
            self, task, trigger_source, trigger_pattern, pretrigger_samples,
            trigger_when):
        cfunc = lib_importer.windll.DAQmxCfgDigPatternRefTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_uint]

        error_code = cfunc(
            task, trigger_source, trigger_pattern, trigger_when,
            pretrigger_samples)
        self.check_for_error(error_code)

    def cfg_dig_pattern_start_trig(
            self, task, trigger_source, trigger_pattern, trigger_when):
        cfunc = lib_importer.windll.DAQmxCfgDigPatternStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            task, trigger_source, trigger_pattern, trigger_when)
        self.check_for_error(error_code)

    def cfg_handshaking_timing(self, task, sample_mode, samps_per_chan):
        cfunc = lib_importer.windll.DAQmxCfgHandshakingTiming
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_ulonglong]

        error_code = cfunc(
            task, sample_mode, samps_per_chan)
        self.check_for_error(error_code)

    def cfg_implicit_timing(self, task, sample_mode, samps_per_chan):
        cfunc = lib_importer.windll.DAQmxCfgImplicitTiming
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_ulonglong]

        error_code = cfunc(
            task, sample_mode, samps_per_chan)
        self.check_for_error(error_code)

    def cfg_pipelined_samp_clk_timing(
            self, task, rate, source, active_edge, sample_mode,
            samps_per_chan):
        cfunc = lib_importer.windll.DAQmxCfgPipelinedSampClkTiming
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_ulonglong]

        error_code = cfunc(
            task, source, rate, active_edge, sample_mode, samps_per_chan)
        self.check_for_error(error_code)

    def cfg_samp_clk_timing(
            self, task, rate, source, active_edge, sample_mode,
            samps_per_chan):
        cfunc = lib_importer.windll.DAQmxCfgSampClkTiming
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_ulonglong]

        error_code = cfunc(
            task, source, rate, active_edge, sample_mode, samps_per_chan)
        self.check_for_error(error_code)

    def cfg_time_start_trig(self, task, when, timescale):
        cfunc = lib_importer.windll.DAQmxCfgTimeStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, AbsoluteTime, ctypes.c_int]

        error_code = cfunc(
            task, AbsoluteTime.from_datetime(when), timescale)
        self.check_for_error(error_code)

    def cfg_watchdog_ao_expir_states(
            self, task, channel_names, expir_state_array, output_type_array):
        cfunc = lib_importer.windll.DAQmxCfgWatchdogAOExpirStates
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        ctypes.c_uint]

        error_code = cfunc(
            task, channel_names, expir_state_array, output_type_array,
            len(output_type_array))
        self.check_for_error(error_code)

    def cfg_watchdog_co_expir_states(
            self, task, channel_names, expir_state_array):
        cfunc = lib_importer.windll.DAQmxCfgWatchdogCOExpirStates
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        ctypes.c_uint]

        error_code = cfunc(
            task, channel_names, expir_state_array, len(expir_state_array))
        self.check_for_error(error_code)

    def cfg_watchdog_do_expir_states(
            self, task, channel_names, expir_state_array):
        cfunc = lib_importer.windll.DAQmxCfgWatchdogDOExpirStates
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        ctypes.c_uint]

        error_code = cfunc(
            task, channel_names, expir_state_array, len(expir_state_array))
        self.check_for_error(error_code)

    def clear_task(self, task):
        cfunc = lib_importer.windll.DAQmxClearTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle]

        error_code = cfunc(
            task)
        self.check_for_error(error_code)

    def clear_teds(self, physical_channel):
        cfunc = lib_importer.windll.DAQmxClearTEDS
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            physical_channel)
        self.check_for_error(error_code)

    def configure_logging(
            self, task, file_path, logging_mode, group_name, operation):
        cfunc = lib_importer.windll.DAQmxConfigureLogging
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int, ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            task, file_path, logging_mode, group_name, operation)
        self.check_for_error(error_code)

    def configure_teds(self, physical_channel, file_path):
        cfunc = lib_importer.windll.DAQmxConfigureTEDS
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str]

        error_code = cfunc(
            physical_channel, file_path)
        self.check_for_error(error_code)

    def connect_terms(
            self, source_terminal, destination_terminal, signal_modifiers):
        cfunc = lib_importer.windll.DAQmxConnectTerms
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            source_terminal, destination_terminal, signal_modifiers)
        self.check_for_error(error_code)

    def control_watchdog_task(self, task, action):
        cfunc = lib_importer.windll.DAQmxControlWatchdogTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, action)
        self.check_for_error(error_code)

    def create_ai_accel4_wire_dc_voltage_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, voltage_excit_source, voltage_excit_val,
            use_excit_for_scaling, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIAccel4WireDCVoltageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double, c_bool32,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, voltage_excit_source, voltage_excit_val,
            use_excit_for_scaling, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_accel_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, current_excit_source, current_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIAccelChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, current_excit_source, current_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_accel_charge_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIAccelChargeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_bridge_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIBridgeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_charge_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIChargeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_current_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, shunt_resistor_loc,
            ext_shunt_resistor_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAICurrentChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, shunt_resistor_loc,
            ext_shunt_resistor_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_current_rms_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, shunt_resistor_loc,
            ext_shunt_resistor_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAICurrentRMSChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, shunt_resistor_loc,
            ext_shunt_resistor_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_force_bridge_polynomial_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, forward_coeffs,
            reverse_coeffs, electrical_units, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIForceBridgePolynomialChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C')), ctypes.c_uint, ctypes.c_int,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, forward_coeffs,
            len(forward_coeffs), reverse_coeffs, len(reverse_coeffs),
            electrical_units, physical_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_force_bridge_table_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, electrical_vals,
            electrical_units, physical_vals, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIForceBridgeTableChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, electrical_vals,
            len(electrical_vals), electrical_units, physical_vals,
            len(physical_vals), physical_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_force_bridge_two_point_lin_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance,
            first_electrical_val, second_electrical_val, electrical_units,
            first_physical_val, second_physical_val, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIForceBridgeTwoPointLinChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance,
            first_electrical_val, second_electrical_val, electrical_units,
            first_physical_val, second_physical_val, physical_units,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_force_iepe_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, current_excit_source, current_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIForceIEPEChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, current_excit_source, current_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_freq_voltage_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, threshold_level, hysteresis, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIFreqVoltageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_double, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, threshold_level, hysteresis, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_microphone_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, units, mic_sensitivity, max_snd_press_level,
            current_excit_source, current_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIMicrophoneChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, units, mic_sensitivity, max_snd_press_level,
            current_excit_source, current_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_pos_eddy_curr_prox_probe_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, sensitivity, sensitivity_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIPosEddyCurrProxProbeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_double, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, sensitivity, sensitivity_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_pos_lvdt_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, sensitivity, sensitivity_units,
            voltage_excit_source, voltage_excit_val, voltage_excit_freq,
            ac_excit_wire_mode, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIPosLVDTChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_double, ctypes.c_int,
                        ctypes.c_int, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, sensitivity, sensitivity_units,
            voltage_excit_source, voltage_excit_val, voltage_excit_freq,
            ac_excit_wire_mode, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_pos_rvdt_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, sensitivity, sensitivity_units,
            voltage_excit_source, voltage_excit_val, voltage_excit_freq,
            ac_excit_wire_mode, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIPosRVDTChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_double, ctypes.c_int,
                        ctypes.c_int, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, sensitivity, sensitivity_units,
            voltage_excit_source, voltage_excit_val, voltage_excit_freq,
            ac_excit_wire_mode, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_power_chan(
            self, task, physical_channel, voltage_setpoint, current_setpoint,
            output_enable, name_to_assign_to_channel):
        cfunc = lib_importer.windll.DAQmxCreateAIPowerChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        c_bool32]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            voltage_setpoint, current_setpoint, output_enable)
        self.check_for_error(error_code)

    def create_ai_pressure_bridge_polynomial_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, forward_coeffs,
            reverse_coeffs, electrical_units, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIPressureBridgePolynomialChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C')), ctypes.c_uint, ctypes.c_int,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, forward_coeffs,
            len(forward_coeffs), reverse_coeffs, len(reverse_coeffs),
            electrical_units, physical_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_pressure_bridge_table_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, electrical_vals,
            electrical_units, physical_vals, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIPressureBridgeTableChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, electrical_vals,
            len(electrical_vals), electrical_units, physical_vals,
            len(physical_vals), physical_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_pressure_bridge_two_point_lin_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance,
            first_electrical_val, second_electrical_val, electrical_units,
            first_physical_val, second_physical_val, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIPressureBridgeTwoPointLinChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance,
            first_electrical_val, second_electrical_val, electrical_units,
            first_physical_val, second_physical_val, physical_units,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_resistance_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIResistanceChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_rosette_strain_gage_chan(
            self, task, physical_channel, rosette_type, gage_orientation,
            rosette_meas_types, name_to_assign_to_channel, min_val, max_val,
            strain_config, voltage_excit_source, voltage_excit_val,
            gage_factor, nominal_gage_resistance, poisson_ratio,
            lead_wire_resistance):
        cfunc = lib_importer.windll.DAQmxCreateAIRosetteStrainGageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        ctypes.c_uint, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, rosette_type, gage_orientation, rosette_meas_types,
            len(rosette_meas_types), strain_config, voltage_excit_source,
            voltage_excit_val, gage_factor, nominal_gage_resistance,
            poisson_ratio, lead_wire_resistance)
        self.check_for_error(error_code)

    def create_ai_strain_gage_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, strain_config, voltage_excit_source,
            voltage_excit_val, gage_factor, initial_bridge_voltage,
            nominal_gage_resistance, poisson_ratio, lead_wire_resistance,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIStrainGageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, strain_config, voltage_excit_source,
            voltage_excit_val, gage_factor, initial_bridge_voltage,
            nominal_gage_resistance, poisson_ratio, lead_wire_resistance,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_temp_built_in_sensor_chan(
            self, task, physical_channel, name_to_assign_to_channel, units):
        cfunc = lib_importer.windll.DAQmxCreateAITempBuiltInSensorChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, units)
        self.check_for_error(error_code)

    def create_ai_thrmcpl_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, thermocouple_type, cjc_source, cjc_val,
            cjc_channel):
        cfunc = lib_importer.windll.DAQmxCreateAIThrmcplChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, thermocouple_type, cjc_source, cjc_val,
            cjc_channel)
        self.check_for_error(error_code)

    def create_ai_thrmstr_chan_iex(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val, a, b, c):
        cfunc = lib_importer.windll.DAQmxCreateAIThrmstrChanIex
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val, a, b, c)
        self.check_for_error(error_code)

    def create_ai_thrmstr_chan_vex(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, voltage_excit_source,
            voltage_excit_val, a, b, c, r_1):
        cfunc = lib_importer.windll.DAQmxCreateAIThrmstrChanVex
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, voltage_excit_source,
            voltage_excit_val, a, b, c, r_1)
        self.check_for_error(error_code)

    def create_ai_torque_bridge_polynomial_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, forward_coeffs,
            reverse_coeffs, electrical_units, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAITorqueBridgePolynomialChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C')), ctypes.c_uint, ctypes.c_int,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, forward_coeffs,
            len(forward_coeffs), reverse_coeffs, len(reverse_coeffs),
            electrical_units, physical_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_torque_bridge_table_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, electrical_vals,
            electrical_units, physical_vals, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAITorqueBridgeTableChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance, electrical_vals,
            len(electrical_vals), electrical_units, physical_vals,
            len(physical_vals), physical_units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_torque_bridge_two_point_lin_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance,
            first_electrical_val, second_electrical_val, electrical_units,
            first_physical_val, second_physical_val, physical_units,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAITorqueBridgeTwoPointLinChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, bridge_config, voltage_excit_source,
            voltage_excit_val, nominal_bridge_resistance,
            first_electrical_val, second_electrical_val, electrical_units,
            first_physical_val, second_physical_val, physical_units,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_velocity_iepe_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, current_excit_source, current_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIVelocityIEPEChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, sensitivity,
            sensitivity_units, current_excit_source, current_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_voltage_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIVoltageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_voltage_chan_with_excit(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, bridge_config,
            voltage_excit_source, voltage_excit_val, use_excit_for_scaling,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIVoltageChanWithExcit
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_int, ctypes.c_double, c_bool32,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, bridge_config,
            voltage_excit_source, voltage_excit_val, use_excit_for_scaling,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ai_voltage_rms_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAIVoltageRMSChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name)
        self.check_for_error(error_code)

    def create_airtd_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, rtd_type, resistance_config, current_excit_source,
            current_excit_val, r_0):
        cfunc = lib_importer.windll.DAQmxCreateAIRTDChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_int, ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, rtd_type, resistance_config, current_excit_source,
            current_excit_val, r_0)
        self.check_for_error(error_code)

    def create_ao_current_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAOCurrentChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ao_func_gen_chan(
            self, task, physical_channel, name_to_assign_to_channel, type,
            freq, amplitude, offset):
        cfunc = lib_importer.windll.DAQmxCreateAOFuncGenChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, type, freq,
            amplitude, offset)
        self.check_for_error(error_code)

    def create_ao_voltage_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateAOVoltageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_ang_encoder_chan(
            self, task, counter, name_to_assign_to_channel, decoding_type,
            zidx_enable, zidx_val, zidx_phase, units, pulses_per_rev,
            initial_angle, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIAngEncoderChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_uint, ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, decoding_type,
            zidx_enable, zidx_val, zidx_phase, units, pulses_per_rev,
            initial_angle, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_ang_velocity_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            decoding_type, units, pulses_per_rev, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIAngVelocityChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_uint,
                        ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val,
            decoding_type, units, pulses_per_rev, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_count_edges_chan(
            self, task, counter, name_to_assign_to_channel, edge,
            initial_count, count_direction):
        cfunc = lib_importer.windll.DAQmxCreateCICountEdgesChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_uint,
                        ctypes.c_int]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, edge, initial_count,
            count_direction)
        self.check_for_error(error_code)

    def create_ci_duty_cycle_chan(
            self, task, counter, name_to_assign_to_channel, min_freq,
            max_freq, edge, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIDutyCycleChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_freq, max_freq,
            edge, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_freq_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units, edge, meas_method, meas_time, divisor, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIFreqChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_uint, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units,
            edge, meas_method, meas_time, divisor, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_lin_encoder_chan(
            self, task, counter, name_to_assign_to_channel, decoding_type,
            zidx_enable, zidx_val, zidx_phase, units, dist_per_pulse,
            initial_pos, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCILinEncoderChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, decoding_type,
            zidx_enable, zidx_val, zidx_phase, units, dist_per_pulse,
            initial_pos, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_lin_velocity_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            decoding_type, units, dist_per_pulse, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCILinVelocityChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val,
            decoding_type, units, dist_per_pulse, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_period_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units, edge, meas_method, meas_time, divisor, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIPeriodChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_uint, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units,
            edge, meas_method, meas_time, divisor, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_pulse_chan_freq(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units):
        cfunc = lib_importer.windll.DAQmxCreateCIPulseChanFreq
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units)
        self.check_for_error(error_code)

    def create_ci_pulse_chan_ticks(
            self, task, counter, name_to_assign_to_channel, source_terminal,
            min_val, max_val):
        cfunc = lib_importer.windll.DAQmxCreateCIPulseChanTicks
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes_byte_str, ctypes.c_double,
                        ctypes.c_double]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, source_terminal,
            min_val, max_val)
        self.check_for_error(error_code)

    def create_ci_pulse_chan_time(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units):
        cfunc = lib_importer.windll.DAQmxCreateCIPulseChanTime
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units)
        self.check_for_error(error_code)

    def create_ci_pulse_width_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units, starting_edge, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIPulseWidthChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units,
            starting_edge, custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_semi_period_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCISemiPeriodChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_ci_two_edge_sep_chan(
            self, task, counter, name_to_assign_to_channel, min_val, max_val,
            units, first_edge, second_edge, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCITwoEdgeSepChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, min_val, max_val, units,
            first_edge, second_edge, custom_scale_name)
        self.check_for_error(error_code)

    def create_cigps_timestamp_chan(
            self, task, counter, name_to_assign_to_channel, units,
            sync_method, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateCIGPSTimestampChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, units, sync_method,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_co_pulse_chan_freq(
            self, task, counter, name_to_assign_to_channel, units, idle_state,
            initial_delay, freq, duty_cycle):
        cfunc = lib_importer.windll.DAQmxCreateCOPulseChanFreq
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, units, idle_state,
            initial_delay, freq, duty_cycle)
        self.check_for_error(error_code)

    def create_co_pulse_chan_ticks(
            self, task, counter, source_terminal, name_to_assign_to_channel,
            idle_state, initial_delay, low_ticks, high_ticks):
        cfunc = lib_importer.windll.DAQmxCreateCOPulseChanTicks
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes_byte_str, ctypes.c_int,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, source_terminal,
            idle_state, initial_delay, low_ticks, high_ticks)
        self.check_for_error(error_code)

    def create_co_pulse_chan_time(
            self, task, counter, name_to_assign_to_channel, units, idle_state,
            initial_delay, low_time, high_time):
        cfunc = lib_importer.windll.DAQmxCreateCOPulseChanTime
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, counter, name_to_assign_to_channel, units, idle_state,
            initial_delay, low_time, high_time)
        self.check_for_error(error_code)

    def create_di_chan(
            self, task, lines, name_to_assign_to_lines, line_grouping):
        cfunc = lib_importer.windll.DAQmxCreateDIChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            task, lines, name_to_assign_to_lines, line_grouping)
        self.check_for_error(error_code)

    def create_do_chan(
            self, task, lines, name_to_assign_to_lines, line_grouping):
        cfunc = lib_importer.windll.DAQmxCreateDOChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            task, lines, name_to_assign_to_lines, line_grouping)
        self.check_for_error(error_code)

    def create_lin_scale(
            self, name, slope, y_intercept, pre_scaled_units, scaled_units):
        cfunc = lib_importer.windll.DAQmxCreateLinScale
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            name, slope, y_intercept, pre_scaled_units, scaled_units)
        self.check_for_error(error_code)

    def create_map_scale(
            self, name, prescaled_min, prescaled_max, scaled_min, scaled_max,
            pre_scaled_units, scaled_units):
        cfunc = lib_importer.windll.DAQmxCreateMapScale
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            name, prescaled_min, prescaled_max, scaled_min, scaled_max,
            pre_scaled_units, scaled_units)
        self.check_for_error(error_code)

    def create_polynomial_scale(
            self, name, forward_coeffs, reverse_coeffs, pre_scaled_units,
            scaled_units):
        cfunc = lib_importer.windll.DAQmxCreatePolynomialScale
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C')), ctypes.c_uint, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            name, forward_coeffs, len(forward_coeffs), reverse_coeffs,
            len(reverse_coeffs), pre_scaled_units, scaled_units)
        self.check_for_error(error_code)

    def create_table_scale(
            self, name, prescaled_vals, scaled_vals, pre_scaled_units,
            scaled_units):
        cfunc = lib_importer.windll.DAQmxCreateTableScale
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.c_uint, wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C')), ctypes.c_uint, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            name, prescaled_vals, len(prescaled_vals), scaled_vals,
            len(scaled_vals), pre_scaled_units, scaled_units)
        self.check_for_error(error_code)

    def create_task(self, session_name):
        new_session_initialized = True
        task = lib_importer.task_handle(0)

        cfunc = lib_importer.windll.DAQmxCreateTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str,
                        ctypes.POINTER(lib_importer.task_handle)]

        error_code = cfunc(
            session_name, ctypes.byref(task))
        self.check_for_error(error_code)
        return task, new_session_initialized

    def create_tedsai_accel_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, current_excit_source,
            current_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIAccelChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, current_excit_source,
            current_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_bridge_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIBridgeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_current_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, shunt_resistor_loc,
            ext_shunt_resistor_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAICurrentChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, shunt_resistor_loc,
            ext_shunt_resistor_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_force_bridge_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIForceBridgeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_force_iepe_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, current_excit_source,
            current_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIForceIEPEChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, current_excit_source,
            current_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_microphone_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, units, max_snd_press_level, current_excit_source,
            current_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIMicrophoneChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, units, max_snd_press_level, current_excit_source,
            current_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_pos_lvdt_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            voltage_excit_freq, ac_excit_wire_mode, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIPosLVDTChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            voltage_excit_freq, ac_excit_wire_mode, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_pos_rvdt_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            voltage_excit_freq, ac_excit_wire_mode, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIPosRVDTChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            voltage_excit_freq, ac_excit_wire_mode, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_pressure_bridge_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIPressureBridgeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_resistance_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIResistanceChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_strain_gage_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            initial_bridge_voltage, lead_wire_resistance, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIStrainGageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            initial_bridge_voltage, lead_wire_resistance, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_thrmcpl_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, cjc_source, cjc_val, cjc_channel):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIThrmcplChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, cjc_source, cjc_val, cjc_channel)
        self.check_for_error(error_code)

    def create_tedsai_thrmstr_chan_iex(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIThrmstrChanIex
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val)
        self.check_for_error(error_code)

    def create_tedsai_thrmstr_chan_vex(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, voltage_excit_source,
            voltage_excit_val, r_1):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIThrmstrChanVex
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, voltage_excit_source,
            voltage_excit_val, r_1)
        self.check_for_error(error_code)

    def create_tedsai_torque_bridge_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAITorqueBridgeChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_double,
                        ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, voltage_excit_source, voltage_excit_val,
            custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_voltage_chan(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIVoltageChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsai_voltage_chan_with_excit(
            self, task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, voltage_excit_source,
            voltage_excit_val, custom_scale_name):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIVoltageChanWithExcit
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_int, ctypes.c_double,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double, ctypes_byte_str]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel,
            terminal_config, min_val, max_val, units, voltage_excit_source,
            voltage_excit_val, custom_scale_name)
        self.check_for_error(error_code)

    def create_tedsairtd_chan(
            self, task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val):
        cfunc = lib_importer.windll.DAQmxCreateTEDSAIRTDChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_double, ctypes.c_double,
                        ctypes.c_int, ctypes.c_int, ctypes.c_int,
                        ctypes.c_double]

        error_code = cfunc(
            task, physical_channel, name_to_assign_to_channel, min_val,
            max_val, units, resistance_config, current_excit_source,
            current_excit_val)
        self.check_for_error(error_code)

    def create_watchdog_timer_task_ex(
            self, device_name, session_name, timeout):
        new_session_initialized = True
        task = lib_importer.task_handle(0)

        cfunc = lib_importer.windll.DAQmxCreateWatchdogTimerTaskEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str,
                        ctypes.POINTER(lib_importer.task_handle),
                        ctypes.c_double]

        error_code = cfunc(
            device_name, session_name, ctypes.byref(task), timeout)
        self.check_for_error(error_code)
        return task, new_session_initialized

    def delete_network_device(self, device_name):
        cfunc = lib_importer.windll.DAQmxDeleteNetworkDevice
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            device_name)
        self.check_for_error(error_code)

    def delete_saved_global_chan(self, channel_name):
        cfunc = lib_importer.windll.DAQmxDeleteSavedGlobalChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            channel_name)
        self.check_for_error(error_code)

    def delete_saved_scale(self, scale_name):
        cfunc = lib_importer.windll.DAQmxDeleteSavedScale
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            scale_name)
        self.check_for_error(error_code)

    def delete_saved_task(self, task_name):
        cfunc = lib_importer.windll.DAQmxDeleteSavedTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            task_name)
        self.check_for_error(error_code)

    def device_supports_cal(self, device_name):
        cal_supported = c_bool32()

        cfunc = lib_importer.windll.DAQmxDeviceSupportsCal
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            device_name, ctypes.byref(cal_supported))
        self.check_for_error(error_code)
        return cal_supported.value

    def disable_ref_trig(self, task):
        cfunc = lib_importer.windll.DAQmxDisableRefTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle]

        error_code = cfunc(
            task)
        self.check_for_error(error_code)

    def disable_start_trig(self, task):
        cfunc = lib_importer.windll.DAQmxDisableStartTrig
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle]

        error_code = cfunc(
            task)
        self.check_for_error(error_code)

    def disconnect_terms(self, source_terminal, destination_terminal):
        cfunc = lib_importer.windll.DAQmxDisconnectTerms
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str]

        error_code = cfunc(
            source_terminal, destination_terminal)
        self.check_for_error(error_code)

    def export_signal(self, task, signal_id, output_terminal):
        cfunc = lib_importer.windll.DAQmxExportSignal
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes_byte_str]

        error_code = cfunc(
            task, signal_id, output_terminal)
        self.check_for_error(error_code)

    def get_analog_power_up_states_with_output_type(
            self, channel_names, array_size):
        state_array = numpy.zeros(array_size, dtype=numpy.float64)
        channel_type_array = numpy.zeros(array_size, dtype=numpy.int32)
        array_size = ctypes.c_uint32(array_size)

        cfunc = lib_importer.cdll.DAQmxGetAnalogPowerUpStatesWithOutputType
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')), wrapped_ndpointer(dtype=numpy.int32,
                        flags=('C','W')), ctypes.POINTER(ctypes.c_uint)]

        error_code = cfunc(
            channel_names, state_array, channel_type_array,
            ctypes.byref(array_size))
        self.check_for_error(error_code)
        return state_array.tolist(), channel_type_array.tolist()

    def get_auto_configured_cdaq_sync_connections(self):
        cfunc = lib_importer.windll.DAQmxGetAutoConfiguredCDAQSyncConnections
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes.c_char_p, ctypes.c_uint]

        temp_size = 0
        while True:
            port_list = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                port_list, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return port_list.value.decode(lib_importer.encoding)

    def get_buffer_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetBufferAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_cal_info_attribute_bool(self, device_name, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_cal_info_attribute_double(self, device_name, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_cal_info_attribute_string(self, device_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                device_name, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_cal_info_attribute_uint32(self, device_name, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_chan_attribute_bool(self, task, channel, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_chan_attribute_double(self, task, channel, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_chan_attribute_double_array(self, task, channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.float64)
            size_or_code = cfunc(
                task, channel, attribute,
                value.ctypes.data_as(ctypes.c_void_p), temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_chan_attribute_int32(self, task, channel, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_chan_attribute_string(self, task, channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, channel, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_chan_attribute_uint32(self, task, channel, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_device_attribute_bool(self, device_name, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_device_attribute_double(self, device_name, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_device_attribute_double_array(self, device_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.float64)
            size_or_code = cfunc(
                device_name, attribute, value.ctypes.data_as(ctypes.c_void_p),
                temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_device_attribute_int32(self, device_name, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_device_attribute_int32_array(self, device_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.int32)
            size_or_code = cfunc(
                device_name, attribute, value.ctypes.data_as(ctypes.c_void_p),
                temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_device_attribute_string(self, device_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                device_name, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_device_attribute_uint32(self, device_name, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_device_attribute_uint32_array(self, device_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetDeviceAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.uint32)
            size_or_code = cfunc(
                device_name, attribute, value.ctypes.data_as(ctypes.c_void_p),
                temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_digital_logic_family_power_up_state(self, device_name):
        logic_family = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxGetDigitalLogicFamilyPowerUpState
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.POINTER(ctypes.c_int)]

        error_code = cfunc(
            device_name, ctypes.byref(logic_family))
        self.check_for_error(error_code)
        return logic_family.value

    def get_digital_power_up_states(self, device_name, channel_name):
        state = []

        args = [device_name]
        argtypes: List[type] = [ctypes_byte_str]

        for index in range(len(channel_name)):
            state_element = ctypes.c_int32()
            state.append(state_element)

            args.append(channel_name[index])
            argtypes.append(ctypes_byte_str)
            
            args.append(ctypes.byref(state_element))
            argtypes.append(ctypes.POINTER(ctypes.c_int32))
            
        args.append(None)
        argtypes.append(ctypes.c_void_p)

        cfunc = lib_importer.cdll.DAQmxGetDigitalPowerUpStates
        with cfunc.arglock:
            cfunc.argtypes = argtypes
            error_code = cfunc(*args)
        self.check_for_error(error_code)
        return [state_element.value for state_element in state]

    def get_digital_pull_up_pull_down_states(self, device_name, channel_name):
        state = []

        args = [device_name]
        argtypes: List[type] = [ctypes_byte_str]

        for index in range(len(channel_name)):
            state_element = ctypes.c_int32()
            state.append(state_element)

            args.append(channel_name[index])
            argtypes.append(ctypes_byte_str)
            
            args.append(ctypes.byref(state_element))
            argtypes.append(ctypes.POINTER(ctypes.c_int32))
            
        args.append(None)
        argtypes.append(ctypes.c_void_p)

        cfunc = lib_importer.cdll.DAQmxGetDigitalPullUpPullDownStates
        with cfunc.arglock:
            cfunc.argtypes = argtypes
            error_code = cfunc(*args)
        self.check_for_error(error_code)
        return [state_element.value for state_element in state]

    def get_disconnected_cdaq_sync_ports(self):
        cfunc = lib_importer.windll.DAQmxGetDisconnectedCDAQSyncPorts
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes.c_char_p, ctypes.c_uint]

        temp_size = 0
        while True:
            port_list = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                port_list, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return port_list.value.decode(lib_importer.encoding)

    def get_exported_signal_attribute_bool(self, task, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_exported_signal_attribute_double(self, task, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_exported_signal_attribute_int32(self, task, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_exported_signal_attribute_string(self, task, attribute):
        cfunc = lib_importer.cdll.DAQmxGetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_exported_signal_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_ext_cal_last_date_and_time(self, device_name):
        year = ctypes.c_uint()
        month = ctypes.c_uint()
        day = ctypes.c_uint()
        hour = ctypes.c_uint()
        minute = ctypes.c_uint()

        cfunc = lib_importer.windll.DAQmxGetExtCalLastDateAndTime
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint)]

        error_code = cfunc(
            device_name, ctypes.byref(year), ctypes.byref(month),
            ctypes.byref(day), ctypes.byref(hour), ctypes.byref(minute))
        self.check_for_error(error_code)
        return year.value, month.value, day.value, hour.value, minute.value

    def get_persisted_chan_attribute_bool(self, channel, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetPersistedChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_persisted_chan_attribute_string(self, channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPersistedChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                channel, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_persisted_scale_attribute_bool(self, scale_name, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetPersistedScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_persisted_scale_attribute_string(self, scale_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPersistedScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                scale_name, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_persisted_task_attribute_bool(self, task_name, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetPersistedTaskAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            task_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_persisted_task_attribute_string(self, task_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPersistedTaskAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task_name, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_physical_chan_attribute_bool(self, physical_channel, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            physical_channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_physical_chan_attribute_bytes(self, physical_channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.uint8)
            size_or_code = cfunc(
                physical_channel, attribute,
                value.ctypes.data_as(ctypes.c_void_p), temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_physical_chan_attribute_double(self, physical_channel, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            physical_channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_physical_chan_attribute_double_array(
            self, physical_channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.float64)
            size_or_code = cfunc(
                physical_channel, attribute,
                value.ctypes.data_as(ctypes.c_void_p), temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_physical_chan_attribute_int32(self, physical_channel, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            physical_channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_physical_chan_attribute_int32_array(
            self, physical_channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.int32)
            size_or_code = cfunc(
                physical_channel, attribute,
                value.ctypes.data_as(ctypes.c_void_p), temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_physical_chan_attribute_string(self, physical_channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                physical_channel, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_physical_chan_attribute_uint32(self, physical_channel, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            physical_channel, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_physical_chan_attribute_uint32_array(
            self, physical_channel, attribute):
        cfunc = lib_importer.cdll.DAQmxGetPhysicalChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.uint32)
            size_or_code = cfunc(
                physical_channel, attribute,
                value.ctypes.data_as(ctypes.c_void_p), temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_read_attribute_bool(self, task, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_read_attribute_double(self, task, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_read_attribute_int32(self, task, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_read_attribute_string(self, task, attribute, size_hint=0):
        cfunc = lib_importer.cdll.DAQmxGetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = size_hint
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_read_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_read_attribute_uint64(self, task, attribute):
        value = ctypes.c_uint64()

        cfunc = lib_importer.cdll.DAQmxGetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_scale_attribute_double(self, scale_name, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_scale_attribute_double_array(self, scale_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.float64)
            size_or_code = cfunc(
                scale_name, attribute, value.ctypes.data_as(ctypes.c_void_p),
                temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_scale_attribute_int32(self, scale_name, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_scale_attribute_string(self, scale_name, attribute):
        cfunc = lib_importer.cdll.DAQmxGetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                scale_name, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_self_cal_last_date_and_time(self, device_name):
        year = ctypes.c_uint()
        month = ctypes.c_uint()
        day = ctypes.c_uint()
        hour = ctypes.c_uint()
        minute = ctypes.c_uint()

        cfunc = lib_importer.windll.DAQmxGetSelfCalLastDateAndTime
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(ctypes.c_uint)]

        error_code = cfunc(
            device_name, ctypes.byref(year), ctypes.byref(month),
            ctypes.byref(day), ctypes.byref(hour), ctypes.byref(minute))
        self.check_for_error(error_code)
        return year.value, month.value, day.value, hour.value, minute.value

    def get_system_info_attribute_string(self, attribute):
        cfunc = lib_importer.cdll.DAQmxGetSystemInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_system_info_attribute_uint32(self, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetSystemInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes.c_int32]

        error_code = cfunc(
            attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_task_attribute_bool(self, task, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetTaskAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_task_attribute_string(self, task, attribute):
        cfunc = lib_importer.cdll.DAQmxGetTaskAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_task_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetTaskAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_bool(self, task, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_double(self, task, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_ex_bool(self, task, device_names, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_ex_double(self, task, device_names, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_ex_int32(self, task, device_names, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_ex_string(self, task, device_names, attribute):
        cfunc = lib_importer.cdll.DAQmxGetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, device_names, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_timing_attribute_ex_uint32(self, task, device_names, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_ex_uint64(self, task, device_names, attribute):
        value = ctypes.c_uint64()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_int32(self, task, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_string(self, task, attribute):
        cfunc = lib_importer.cdll.DAQmxGetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_timing_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_timing_attribute_uint64(self, task, attribute):
        value = ctypes.c_uint64()

        cfunc = lib_importer.cdll.DAQmxGetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_trig_attribute_bool(self, task, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_trig_attribute_double(self, task, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_trig_attribute_double_array(self, task, attribute):
        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.float64)
            size_or_code = cfunc(
                task, attribute, value.ctypes.data_as(ctypes.c_void_p),
                temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_trig_attribute_int32(self, task, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_trig_attribute_int32_array(self, task, attribute):
        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = 0
        while True:
            value = numpy.zeros(temp_size, dtype=numpy.int32)
            size_or_code = cfunc(
                task, attribute, value.ctypes.data_as(ctypes.c_void_p),
                temp_size)
            if is_array_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.tolist()

    def get_trig_attribute_string(self, task, attribute):
        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_trig_attribute_timestamp(self, task, attribute):
        value = AbsoluteTime()

        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.to_datetime()

    def get_trig_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_watchdog_attribute_bool(self, task, lines, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_watchdog_attribute_double(self, task, lines, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_watchdog_attribute_int32(self, task, lines, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_watchdog_attribute_string(self, task, lines, attribute):
        cfunc = lib_importer.cdll.DAQmxGetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        temp_size = 0
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, lines, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_write_attribute_bool(self, task, attribute):
        value = c_bool32()

        cfunc = lib_importer.cdll.DAQmxGetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_write_attribute_double(self, task, attribute):
        value = ctypes.c_double()

        cfunc = lib_importer.cdll.DAQmxGetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_write_attribute_int32(self, task, attribute):
        value = ctypes.c_int32()

        cfunc = lib_importer.cdll.DAQmxGetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_write_attribute_string(self, task, attribute, size_hint=0):
        cfunc = lib_importer.cdll.DAQmxGetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        temp_size = size_hint
        while True:
            value = ctypes.create_string_buffer(temp_size)
            size_or_code = cfunc(
                task, attribute, value, temp_size)
            if is_string_buffer_too_small(size_or_code):
                # Buffer size must have changed between calls; check again.
                temp_size = 0
            elif size_or_code > 0 and temp_size == 0:
                # Buffer size obtained, use to retrieve data.
                temp_size = size_or_code
            else:
                break
        self.check_for_error(size_or_code)
        return value.value.decode(lib_importer.encoding)

    def get_write_attribute_uint32(self, task, attribute):
        value = ctypes.c_uint32()

        cfunc = lib_importer.cdll.DAQmxGetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def get_write_attribute_uint64(self, task, attribute):
        value = ctypes.c_uint64()

        cfunc = lib_importer.cdll.DAQmxGetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.byref(value))
        self.check_for_error(error_code)
        return value.value

    def is_task_done(self, task):
        is_task_done = c_bool32()

        cfunc = lib_importer.windll.DAQmxIsTaskDone
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, ctypes.byref(is_task_done))
        self.check_for_error(error_code)
        return is_task_done.value

    def load_task(self, session_name):
        new_session_initialized = True
        task = lib_importer.task_handle(0)

        cfunc = lib_importer.windll.DAQmxLoadTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str,
                        ctypes.POINTER(lib_importer.task_handle)]

        error_code = cfunc(
            session_name, ctypes.byref(task))
        self.check_for_error(error_code)
        return task, new_session_initialized

    def perform_bridge_offset_nulling_cal_ex(
            self, task, channel, skip_unsupported_channels):
        cfunc = lib_importer.windll.DAQmxPerformBridgeOffsetNullingCalEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str, c_bool32]

        error_code = cfunc(
            task, channel, skip_unsupported_channels)
        self.check_for_error(error_code)

    def perform_bridge_shunt_cal_ex(
            self, task, channel, shunt_resistor_value,
            shunt_resistor_location, shunt_resistor_select,
            shunt_resistor_source, bridge_resistance,
            skip_unsupported_channels):
        cfunc = lib_importer.windll.DAQmxPerformBridgeShuntCalEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_int, ctypes.c_double, c_bool32]

        error_code = cfunc(
            task, channel, shunt_resistor_value, shunt_resistor_location,
            shunt_resistor_select, shunt_resistor_source, bridge_resistance,
            skip_unsupported_channels)
        self.check_for_error(error_code)

    def perform_strain_shunt_cal_ex(
            self, task, channel, shunt_resistor_value,
            shunt_resistor_location, shunt_resistor_select,
            shunt_resistor_source, skip_unsupported_channels):
        cfunc = lib_importer.windll.DAQmxPerformStrainShuntCalEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_double, ctypes.c_int, ctypes.c_int,
                        ctypes.c_int, c_bool32]

        error_code = cfunc(
            task, channel, shunt_resistor_value, shunt_resistor_location,
            shunt_resistor_select, shunt_resistor_source,
            skip_unsupported_channels)
        self.check_for_error(error_code)

    def perform_thrmcpl_lead_offset_nulling_cal(
            self, task, channel, skip_unsupported_channels):
        cfunc = lib_importer.windll.DAQmxPerformThrmcplLeadOffsetNullingCal
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str, c_bool32]

        error_code = cfunc(
            task, channel, skip_unsupported_channels)
        self.check_for_error(error_code)

    def read_analog_f64(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadAnalogF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_analog_scalar_f64(self, task, timeout):
        value = ctypes.c_double()

        cfunc = lib_importer.windll.DAQmxReadAnalogScalarF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(value), None)
        self.check_for_error(error_code)
        return value.value

    def read_binary_i16(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadBinaryI16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.int16, flags=('C','W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_binary_i32(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadBinaryI32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C','W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_binary_u16(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadBinaryU16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint16,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_binary_u32(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadBinaryU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_counter_f64(self, task, num_samps_per_chan, timeout, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCounterF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, read_array, read_array.size,
            ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_counter_f64_ex(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCounterF64Ex
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_counter_scalar_f64(self, task, timeout):
        value = ctypes.c_double()

        cfunc = lib_importer.windll.DAQmxReadCounterScalarF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(value), None)
        self.check_for_error(error_code)
        return value.value

    def read_counter_scalar_u32(self, task, timeout):
        value = ctypes.c_uint()

        cfunc = lib_importer.windll.DAQmxReadCounterScalarU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(value), None)
        self.check_for_error(error_code)
        return value.value

    def read_counter_u32(self, task, num_samps_per_chan, timeout, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCounterU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, wrapped_ndpointer(dtype=numpy.uint32,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, read_array, read_array.size,
            ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_counter_u32_ex(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCounterU32Ex
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_ctr_freq(
            self, task, num_samps_per_chan, timeout, interleaved,
            read_array_frequency, read_array_duty_cycle):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCtrFreq
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')),
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, interleaved,
            read_array_frequency, read_array_duty_cycle,
            read_array_duty_cycle.size, ctypes.byref(samps_per_chan_read),
            None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array_frequency, read_array_duty_cycle, samps_per_chan_read.value

    def read_ctr_freq_scalar(self, task, timeout):
        frequency = ctypes.c_double()
        duty_cycle = ctypes.c_double()

        cfunc = lib_importer.windll.DAQmxReadCtrFreqScalar
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(frequency), ctypes.byref(duty_cycle),
            None)
        self.check_for_error(error_code)
        return frequency.value, duty_cycle.value

    def read_ctr_ticks(
            self, task, num_samps_per_chan, timeout, interleaved,
            read_array_high_ticks, read_array_low_ticks):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCtrTicks
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32,
                        flags=('C','W')),
                        wrapped_ndpointer(dtype=numpy.uint32,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, interleaved,
            read_array_high_ticks, read_array_low_ticks,
            read_array_low_ticks.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array_high_ticks, read_array_low_ticks, samps_per_chan_read.value

    def read_ctr_ticks_scalar(self, task, timeout):
        high_ticks = ctypes.c_uint32()
        low_ticks = ctypes.c_uint32()

        cfunc = lib_importer.windll.DAQmxReadCtrTicksScalar
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_uint32),
                        ctypes.POINTER(ctypes.c_uint32),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(high_ticks), ctypes.byref(low_ticks),
            None)
        self.check_for_error(error_code)
        return high_ticks.value, low_ticks.value

    def read_ctr_time(
            self, task, num_samps_per_chan, timeout, interleaved,
            read_array_high_time, read_array_low_time):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadCtrTime
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')),
                        wrapped_ndpointer(dtype=numpy.float64,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, interleaved,
            read_array_high_time, read_array_low_time,
            read_array_low_time.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array_high_time, read_array_low_time, samps_per_chan_read.value

    def read_ctr_time_scalar(self, task, timeout):
        high_time = ctypes.c_double()
        low_time = ctypes.c_double()

        cfunc = lib_importer.windll.DAQmxReadCtrTimeScalar
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(high_time), ctypes.byref(low_time),
            None)
        self.check_for_error(error_code)
        return high_time.value, low_time.value

    def read_digital_lines(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()
        num_bytes_per_samp = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadDigitalLines
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=bool, flags=('C','W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read),
            ctypes.byref(num_bytes_per_samp), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value, num_bytes_per_samp.value

    def read_digital_scalar_u32(self, task, timeout):
        value = ctypes.c_uint()

        cfunc = lib_importer.windll.DAQmxReadDigitalScalarU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_uint),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(value), None)
        self.check_for_error(error_code)
        return value.value

    def read_digital_u16(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadDigitalU16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint16,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_digital_u32(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadDigitalU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32,
                        flags=('C','W')), ctypes.c_uint,
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_digital_u8(
            self, task, num_samps_per_chan, timeout, fill_mode, read_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadDigitalU8
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint8, flags=('C','W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode, read_array,
            read_array.size, ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)
        return read_array, samps_per_chan_read.value

    def read_power_scalar_f64(self, task, timeout):
        voltage = ctypes.c_double()
        current = ctypes.c_double()

        cfunc = lib_importer.windll.DAQmxReadPowerScalarF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double,
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(ctypes.c_double),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, timeout, ctypes.byref(voltage), ctypes.byref(current), None)
        self.check_for_error(error_code)
        return voltage.value, current.value

    def register_done_event(
            self, task, options, callback_function, callback_data):
        DAQmxDoneEventCallbackPtr = ctypes.CFUNCTYPE(
            ctypes.c_int32, lib_importer.task_handle, ctypes.c_int,
            ctypes.c_void_p)

        cfunc = lib_importer.windll.DAQmxRegisterDoneEvent
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_uint,
                        DAQmxDoneEventCallbackPtr,
                        ctypes.POINTER(ctypes.c_void_p)]

        assert callback_function is not None
        callback_method_ptr = DAQmxDoneEventCallbackPtr(callback_function)

        error_code = cfunc(
            task, options, callback_method_ptr, callback_data)
        self.check_for_error(error_code)

        return LibraryEventHandler(callback_method_ptr)

    def register_every_n_samples_event(
            self, task, every_n_samples_event_type, n_samples, options,
            callback_function, callback_data):
        DAQmxEveryNSamplesEventCallbackPtr = ctypes.CFUNCTYPE(
            ctypes.c_int32, lib_importer.task_handle, ctypes.c_int,
            ctypes.c_uint, ctypes.c_void_p)

        cfunc = lib_importer.windll.DAQmxRegisterEveryNSamplesEvent
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_uint,
                        ctypes.c_uint, DAQmxEveryNSamplesEventCallbackPtr,
                        ctypes.POINTER(ctypes.c_void_p)]

        assert callback_function is not None
        callback_method_ptr = DAQmxEveryNSamplesEventCallbackPtr(callback_function)

        error_code = cfunc(
            task, every_n_samples_event_type, n_samples, options,
            callback_method_ptr, callback_data)
        self.check_for_error(error_code)

        return LibraryEventHandler(callback_method_ptr)

    def register_signal_event(
            self, task, signal_id, options, callback_function, callback_data):
        DAQmxSignalEventCallbackPtr = ctypes.CFUNCTYPE(
            ctypes.c_int32, lib_importer.task_handle, ctypes.c_int,
            ctypes.c_void_p)

        cfunc = lib_importer.windll.DAQmxRegisterSignalEvent
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_uint,
                        DAQmxSignalEventCallbackPtr,
                        ctypes.POINTER(ctypes.c_void_p)]

        assert callback_function is not None
        callback_method_ptr = DAQmxSignalEventCallbackPtr(callback_function)

        error_code = cfunc(
            task, signal_id, options, callback_method_ptr, callback_data)
        self.check_for_error(error_code)

        return LibraryEventHandler(callback_method_ptr)

    def remove_cdaq_sync_connection(self, port_list):
        cfunc = lib_importer.windll.DAQmxRemoveCDAQSyncConnection
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            port_list)
        self.check_for_error(error_code)

    def reserve_network_device(self, device_name, override_reservation):
        cfunc = lib_importer.windll.DAQmxReserveNetworkDevice
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, c_bool32]

        error_code = cfunc(
            device_name, override_reservation)
        self.check_for_error(error_code)

    def reset_buffer_attribute(self, task, attribute):
        cfunc = lib_importer.windll.DAQmxResetBufferAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute)
        self.check_for_error(error_code)

    def reset_chan_attribute(self, task, channel, attribute):
        cfunc = lib_importer.windll.DAQmxResetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute)
        self.check_for_error(error_code)

    def reset_device(self, device_name):
        cfunc = lib_importer.windll.DAQmxResetDevice
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            device_name)
        self.check_for_error(error_code)

    def reset_exported_signal_attribute(self, task, attribute):
        cfunc = lib_importer.windll.DAQmxResetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, attribute)
        self.check_for_error(error_code)

    def reset_read_attribute(self, task, attribute):
        cfunc = lib_importer.windll.DAQmxResetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, attribute)
        self.check_for_error(error_code)

    def reset_timing_attribute(self, task, attribute):
        cfunc = lib_importer.windll.DAQmxResetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, attribute)
        self.check_for_error(error_code)

    def reset_timing_attribute_ex(self, task, device_names, attribute):
        cfunc = lib_importer.windll.DAQmxResetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int]

        error_code = cfunc(
            task, device_names, attribute)
        self.check_for_error(error_code)

    def reset_trig_attribute(self, task, attribute):
        cfunc = lib_importer.windll.DAQmxResetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, attribute)
        self.check_for_error(error_code)

    def reset_watchdog_attribute(self, task, lines, attribute):
        cfunc = lib_importer.windll.DAQmxResetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int]

        error_code = cfunc(
            task, lines, attribute)
        self.check_for_error(error_code)

    def reset_write_attribute(self, task, attribute):
        cfunc = lib_importer.windll.DAQmxResetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, attribute)
        self.check_for_error(error_code)

    def restore_last_ext_cal_const(self, device_name):
        cfunc = lib_importer.windll.DAQmxRestoreLastExtCalConst
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            device_name)
        self.check_for_error(error_code)

    def save_global_chan(self, task, channel_name, save_as, author, options):
        cfunc = lib_importer.windll.DAQmxSaveGlobalChan
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes_byte_str, ctypes.c_uint32]

        error_code = cfunc(
            task, channel_name, save_as, author, options)
        self.check_for_error(error_code)

    def save_scale(self, scale_name, save_as, author, options):
        cfunc = lib_importer.windll.DAQmxSaveScale
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str, ctypes_byte_str,
                        ctypes.c_uint32]

        error_code = cfunc(
            scale_name, save_as, author, options)
        self.check_for_error(error_code)

    def save_task(self, task, save_as, author, options):
        cfunc = lib_importer.windll.DAQmxSaveTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes_byte_str, ctypes.c_uint32]

        error_code = cfunc(
            task, save_as, author, options)
        self.check_for_error(error_code)

    def self_cal(self, device_name):
        cfunc = lib_importer.windll.DAQmxSelfCal
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            device_name)
        self.check_for_error(error_code)

    def self_test_device(self, device_name):
        cfunc = lib_importer.windll.DAQmxSelfTestDevice
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            device_name)
        self.check_for_error(error_code)

    def set_analog_power_up_states(
            self, device_name, channel_names, state, channel_type):
        args = [device_name]
        argtypes: List[type] = [ctypes_byte_str]

        for index in range(len(channel_names)):

            args.append(channel_names[index])
            argtypes.append(ctypes_byte_str)
            
            args.append(state[index])
            argtypes.append(ctypes.c_double)
            
            args.append(channel_type[index])
            argtypes.append(ctypes.c_int32)
            
        args.append(None)
        argtypes.append(ctypes.c_void_p)

        cfunc = lib_importer.cdll.DAQmxSetAnalogPowerUpStates
        with cfunc.arglock:
            cfunc.argtypes = argtypes
            error_code = cfunc(*args)
        self.check_for_error(error_code)

    def set_analog_power_up_states_with_output_type(
            self, channel_names, state_array, channel_type_array):
        cfunc = lib_importer.cdll.DAQmxSetAnalogPowerUpStatesWithOutputType
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        ctypes.c_uint]

        error_code = cfunc(
            channel_names, state_array, channel_type_array,
            len(channel_type_array))
        self.check_for_error(error_code)

    def set_buffer_attribute_uint32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetBufferAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_cal_info_attribute_bool(self, device_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_cal_info_attribute_double(self, device_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_cal_info_attribute_string(self, device_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_cal_info_attribute_uint32(self, device_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetCalInfoAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            device_name, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_chan_attribute_bool(self, task, channel, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_chan_attribute_double(self, task, channel, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_chan_attribute_double_array(self, task, channel, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, value.ctypes.data_as(ctypes.c_void_p),
            len(value))
        self.check_for_error(error_code)

    def set_chan_attribute_int32(self, task, channel, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_chan_attribute_string(self, task, channel, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_chan_attribute_uint32(self, task, channel, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetChanAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, channel, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_digital_logic_family_power_up_state(
            self, device_name, logic_family):
        cfunc = lib_importer.windll.DAQmxSetDigitalLogicFamilyPowerUpState
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            device_name, logic_family)
        self.check_for_error(error_code)

    def set_digital_power_up_states(self, device_name, channel_names, state):
        args = [device_name]
        argtypes: List[type] = [ctypes_byte_str]

        for index in range(len(channel_names)):

            args.append(channel_names[index])
            argtypes.append(ctypes_byte_str)
            
            args.append(state[index])
            argtypes.append(ctypes.c_int32)
            
        args.append(None)
        argtypes.append(ctypes.c_void_p)

        cfunc = lib_importer.cdll.DAQmxSetDigitalPowerUpStates
        with cfunc.arglock:
            cfunc.argtypes = argtypes
            error_code = cfunc(*args)
        self.check_for_error(error_code)

    def set_digital_pull_up_pull_down_states(
            self, device_name, channel_names, state):
        args = [device_name]
        argtypes: List[type] = [ctypes_byte_str]

        for index in range(len(channel_names)):

            args.append(channel_names[index])
            argtypes.append(ctypes_byte_str)
            
            args.append(state[index])
            argtypes.append(ctypes.c_int32)
            
        args.append(None)
        argtypes.append(ctypes.c_void_p)

        cfunc = lib_importer.cdll.DAQmxSetDigitalPullUpPullDownStates
        with cfunc.arglock:
            cfunc.argtypes = argtypes
            error_code = cfunc(*args)
        self.check_for_error(error_code)

    def set_exported_signal_attribute_bool(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_exported_signal_attribute_double(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_exported_signal_attribute_int32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_exported_signal_attribute_string(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_exported_signal_attribute_uint32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetExportedSignalAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_read_attribute_bool(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_read_attribute_double(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_read_attribute_int32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_read_attribute_string(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_read_attribute_uint32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_read_attribute_uint64(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetReadAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint64(value))
        self.check_for_error(error_code)

    def set_runtime_environment(
            self, environment, environment_version, reserved_1, reserved_2):
        cfunc = lib_importer.windll.DAQmxSetRuntimeEnvironment
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str, ctypes_byte_str,
                        ctypes_byte_str]

        error_code = cfunc(
            environment, environment_version, reserved_1, reserved_2)
        self.check_for_error(error_code)

    def set_scale_attribute_double(self, scale_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_scale_attribute_double_array(self, scale_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, value.ctypes.data_as(ctypes.c_void_p),
            len(value))
        self.check_for_error(error_code)

    def set_scale_attribute_int32(self, scale_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_scale_attribute_string(self, scale_name, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetScaleAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes.c_int32]

        error_code = cfunc(
            scale_name, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_timing_attribute_bool(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_timing_attribute_double(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_timing_attribute_ex_bool(
            self, task, device_names, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_timing_attribute_ex_double(
            self, task, device_names, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_timing_attribute_ex_int32(
            self, task, device_names, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_timing_attribute_ex_string(
            self, task, device_names, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_timing_attribute_ex_uint32(
            self, task, device_names, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_timing_attribute_ex_uint64(
            self, task, device_names, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttributeEx
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, device_names, attribute, ctypes.c_uint64(value))
        self.check_for_error(error_code)

    def set_timing_attribute_int32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_timing_attribute_string(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_timing_attribute_uint32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_timing_attribute_uint64(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTimingAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint64(value))
        self.check_for_error(error_code)

    def set_trig_attribute_bool(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_trig_attribute_double(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_trig_attribute_double_array(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.ctypes.data_as(ctypes.c_void_p), len(value))
        self.check_for_error(error_code)

    def set_trig_attribute_int32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_trig_attribute_int32_array(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.ctypes.data_as(ctypes.c_void_p), len(value))
        self.check_for_error(error_code)

    def set_trig_attribute_string(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_trig_attribute_timestamp(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, AbsoluteTime.from_datetime(value))
        self.check_for_error(error_code)

    def set_trig_attribute_uint32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetTrigAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_watchdog_attribute_bool(self, task, lines, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_watchdog_attribute_double(self, task, lines, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_watchdog_attribute_int32(self, task, lines, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_watchdog_attribute_string(self, task, lines, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWatchdogAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str,
                        ctypes.c_int32]

        error_code = cfunc(
            task, lines, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_write_attribute_bool(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, c_bool32(value))
        self.check_for_error(error_code)

    def set_write_attribute_double(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_double(value))
        self.check_for_error(error_code)

    def set_write_attribute_int32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_int32(value))
        self.check_for_error(error_code)

    def set_write_attribute_string(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, value.encode(lib_importer.encoding))
        self.check_for_error(error_code)

    def set_write_attribute_uint32(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint32(value))
        self.check_for_error(error_code)

    def set_write_attribute_uint64(self, task, attribute, value):
        cfunc = lib_importer.cdll.DAQmxSetWriteAttribute
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32]

        error_code = cfunc(
            task, attribute, ctypes.c_uint64(value))
        self.check_for_error(error_code)

    def start_new_file(self, task, file_path):
        cfunc = lib_importer.windll.DAQmxStartNewFile
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes_byte_str]

        error_code = cfunc(
            task, file_path)
        self.check_for_error(error_code)

    def start_task(self, task):
        cfunc = lib_importer.windll.DAQmxStartTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle]

        error_code = cfunc(
            task)
        self.check_for_error(error_code)

    def stop_task(self, task):
        cfunc = lib_importer.windll.DAQmxStopTask
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle]

        error_code = cfunc(
            task)
        self.check_for_error(error_code)

    def task_control(self, task, action):
        cfunc = lib_importer.windll.DAQmxTaskControl
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int]

        error_code = cfunc(
            task, action)
        self.check_for_error(error_code)

    def tristate_output_term(self, output_terminal):
        cfunc = lib_importer.windll.DAQmxTristateOutputTerm
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            output_terminal)
        self.check_for_error(error_code)

    def unregister_done_event(self, task):
        DAQmxDoneEventCallbackPtr = ctypes.CFUNCTYPE(
            ctypes.c_int32, lib_importer.task_handle, ctypes.c_int,
            ctypes.c_void_p)

        cfunc = lib_importer.windll.DAQmxRegisterDoneEvent
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_uint,
                        DAQmxDoneEventCallbackPtr,
                        ctypes.POINTER(ctypes.c_void_p)]

        options = 0
        callback_method_ptr = DAQmxDoneEventCallbackPtr()  # type: ignore  # typeshed is missing no-argument constructor overload
        callback_data = None

        error_code = cfunc(
            task, options, callback_method_ptr, callback_data)
        self.check_for_error(error_code)

    def unregister_every_n_samples_event(
            self, task, every_n_samples_event_type):
        DAQmxEveryNSamplesEventCallbackPtr = ctypes.CFUNCTYPE(
            ctypes.c_int32, lib_importer.task_handle, ctypes.c_int,
            ctypes.c_uint, ctypes.c_void_p)

        cfunc = lib_importer.windll.DAQmxRegisterEveryNSamplesEvent
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_uint,
                        ctypes.c_uint, DAQmxEveryNSamplesEventCallbackPtr,
                        ctypes.POINTER(ctypes.c_void_p)]

        n_samples = 0
        options = 0
        callback_method_ptr = DAQmxEveryNSamplesEventCallbackPtr()  # type: ignore  # typeshed is missing no-argument constructor overload
        callback_data = None

        error_code = cfunc(
            task, every_n_samples_event_type, n_samples, options,
            callback_method_ptr, callback_data)
        self.check_for_error(error_code)

    def unregister_signal_event(self, task, signal_id):
        DAQmxSignalEventCallbackPtr = ctypes.CFUNCTYPE(
            ctypes.c_int32, lib_importer.task_handle, ctypes.c_int,
            ctypes.c_void_p)

        cfunc = lib_importer.windll.DAQmxRegisterSignalEvent
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_uint,
                        DAQmxSignalEventCallbackPtr,
                        ctypes.POINTER(ctypes.c_void_p)]

        options = 0
        callback_method_ptr = DAQmxSignalEventCallbackPtr()  # type: ignore  # typeshed is missing no-argument constructor overload
        callback_data = None

        error_code = cfunc(
            task, signal_id, options, callback_method_ptr, callback_data)
        self.check_for_error(error_code)

    def unreserve_network_device(self, device_name):
        cfunc = lib_importer.windll.DAQmxUnreserveNetworkDevice
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str]

        error_code = cfunc(
            device_name)
        self.check_for_error(error_code)

    def wait_for_valid_timestamp(self, task, timestamp_event, timeout):
        timestamp = AbsoluteTime()

        cfunc = lib_importer.windll.DAQmxWaitForValidTimestamp
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int32,
                        ctypes.c_double, ctypes.POINTER(AbsoluteTime)]

        error_code = cfunc(
            task, timestamp_event, timeout, ctypes.byref(timestamp))
        self.check_for_error(error_code)
        return timestamp.to_datetime()

    def wait_until_task_done(self, task, time_to_wait):
        cfunc = lib_importer.windll.DAQmxWaitUntilTaskDone
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_double]

        error_code = cfunc(
            task, time_to_wait)
        self.check_for_error(error_code)

    def write_analog_f64(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteAnalogF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_analog_scalar_f64(self, task, auto_start, timeout, value):
        cfunc = lib_importer.windll.DAQmxWriteAnalogScalarF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, c_bool32, ctypes.c_double,
                        ctypes.c_double, ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, auto_start, timeout, value, None)
        self.check_for_error(error_code)

    def write_binary_i16(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteBinaryI16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.int16, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_binary_i32(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteBinaryI32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.int32, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_binary_u16(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteBinaryU16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint16, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_binary_u32(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteBinaryU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_ctr_freq(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            frequency, duty_cycle):
        num_samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteCtrFreq
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            frequency, duty_cycle, ctypes.byref(num_samps_per_chan_written),
            None)
        self.check_for_error(error_code, samps_per_chan_written=num_samps_per_chan_written.value)
        return num_samps_per_chan_written.value

    def write_ctr_freq_scalar(
            self, task, auto_start, timeout, frequency, duty_cycle):
        cfunc = lib_importer.windll.DAQmxWriteCtrFreqScalar
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, c_bool32, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double,
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, auto_start, timeout, frequency, duty_cycle, None)
        self.check_for_error(error_code)

    def write_ctr_ticks(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            high_ticks, low_ticks):
        num_samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteCtrTicks
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.uint32, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            high_ticks, low_ticks, ctypes.byref(num_samps_per_chan_written),
            None)
        self.check_for_error(error_code, samps_per_chan_written=num_samps_per_chan_written.value)
        return num_samps_per_chan_written.value

    def write_ctr_ticks_scalar(
            self, task, auto_start, timeout, high_ticks, low_ticks):
        cfunc = lib_importer.windll.DAQmxWriteCtrTicksScalar
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, c_bool32, ctypes.c_double,
                        ctypes.c_uint32, ctypes.c_uint32,
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, auto_start, timeout, high_ticks, low_ticks, None)
        self.check_for_error(error_code)

    def write_ctr_time(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            high_time, low_time):
        num_samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteCtrTime
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            high_time, low_time, ctypes.byref(num_samps_per_chan_written),
            None)
        self.check_for_error(error_code, samps_per_chan_written=num_samps_per_chan_written.value)
        return num_samps_per_chan_written.value

    def write_ctr_time_scalar(
            self, task, auto_start, timeout, high_time, low_time):
        cfunc = lib_importer.windll.DAQmxWriteCtrTimeScalar
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, c_bool32, ctypes.c_double,
                        ctypes.c_double, ctypes.c_double,
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, auto_start, timeout, high_time, low_time, None)
        self.check_for_error(error_code)

    def write_digital_lines(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteDigitalLines
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=bool, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_digital_scalar_u32(self, task, auto_start, timeout, value):
        cfunc = lib_importer.windll.DAQmxWriteDigitalScalarU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, c_bool32, ctypes.c_double,
                        ctypes.c_uint, ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, auto_start, timeout, value, None)
        self.check_for_error(error_code)

    def write_digital_u16(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteDigitalU16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint16, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_digital_u32(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteDigitalU32
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint32, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_digital_u8(
            self, task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteDigitalU8
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double, ctypes.c_int,
                        wrapped_ndpointer(dtype=numpy.uint8, flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, auto_start, timeout, data_layout,
            write_array, ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)
        return samps_per_chan_written.value

    def write_to_teds_from_array(
            self, physical_channel, bit_stream, basic_teds_options):
        cfunc = lib_importer.windll.DAQmxWriteToTEDSFromArray
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, wrapped_ndpointer(dtype=numpy.uint8,
                        flags=('C')), ctypes.c_uint, ctypes.c_int]

        error_code = cfunc(
            physical_channel, bit_stream, len(bit_stream), basic_teds_options)
        self.check_for_error(error_code)

    def write_to_teds_from_file(
            self, physical_channel, file_path, basic_teds_options):
        cfunc = lib_importer.windll.DAQmxWriteToTEDSFromFile
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        ctypes_byte_str, ctypes_byte_str, ctypes.c_int]

        error_code = cfunc(
            physical_channel, file_path, basic_teds_options)
        self.check_for_error(error_code)

    def get_error_string(self, error_code):
        error_buffer = ctypes.create_string_buffer(2048)

        cfunc = lib_importer.windll.DAQmxGetErrorString
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [ctypes.c_int, ctypes.c_char_p,
                                      ctypes.c_uint]

        query_error_code = cfunc(error_code, error_buffer, 2048)
        if query_error_code < 0:
            _logger.error('Failed to get error string for error code %d. DAQmxGetErrorString returned error code %d.', error_code, query_error_code)
            return 'Failed to retrieve error description.'
        return error_buffer.value.decode(lib_importer.encoding)

    def get_extended_error_info(self):
        error_buffer = ctypes.create_string_buffer(2048)

        cfunc = lib_importer.windll.DAQmxGetExtendedErrorInfo
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [ctypes.c_char_p, ctypes.c_uint]

        query_error_code = cfunc(error_buffer, 2048)
        if query_error_code < 0:
            _logger.error('Failed to get extended error info. DAQmxGetExtendedErrorInfo returned error code %d.', query_error_code)
            return 'Failed to retrieve error description.'
        return error_buffer.value.decode(lib_importer.encoding)

    def read_power_binary_i16(
            self, task, num_samps_per_chan, timeout, fill_mode,
            read_voltage_array, read_current_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadPowerBinaryI16
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_double,
                        c_bool32,
                        wrapped_ndpointer(dtype=numpy.int16, flags=('C', 'W')),
                        wrapped_ndpointer(dtype=numpy.int16, flags=('C', 'W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode,
            read_voltage_array, read_current_array, read_voltage_array.size,
            ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)

        return read_voltage_array, read_current_array, samps_per_chan_read.value

    def read_power_f64(
            self, task, num_samps_per_chan, timeout, fill_mode,
            read_voltage_array, read_current_array):
        samps_per_chan_read = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadPowerF64
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_double,
                        c_bool32,
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C', 'W')),
                        wrapped_ndpointer(dtype=numpy.float64, flags=('C', 'W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, fill_mode,
            read_voltage_array, read_current_array, read_voltage_array.size,
            ctypes.byref(samps_per_chan_read), None)
        self.check_for_error(error_code, samps_per_chan_read=samps_per_chan_read.value)

        return read_voltage_array, read_current_array, samps_per_chan_read.value

    def read_raw(self, task, num_samps_per_chan, timeout, read_array):
        samples_read = ctypes.c_int()
        number_of_bytes_per_sample = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxReadRaw
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, ctypes.c_double,
                        wrapped_ndpointer(dtype=read_array.dtype, flags=('C', 'W')),
                        ctypes.c_uint, ctypes.POINTER(ctypes.c_int),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task, num_samps_per_chan, timeout, read_array,
            read_array.nbytes, ctypes.byref(samples_read),
            ctypes.byref(number_of_bytes_per_sample), None)
        self.check_for_error(error_code, samps_per_chan_read=samples_read.value)

        return read_array, samples_read.value, number_of_bytes_per_sample.value

    def write_raw(
            self, task_handle, num_samps_per_chan, auto_start, timeout, numpy_array):
        samps_per_chan_written = ctypes.c_int()

        cfunc = lib_importer.windll.DAQmxWriteRaw
        if cfunc.argtypes is None:
            with cfunc.arglock:
                if cfunc.argtypes is None:
                    cfunc.argtypes = [
                        lib_importer.task_handle, ctypes.c_int, c_bool32,
                        ctypes.c_double,
                        wrapped_ndpointer(dtype=numpy_array.dtype,
                                        flags=('C')),
                        ctypes.POINTER(ctypes.c_int), ctypes.POINTER(c_bool32)]

        error_code = cfunc(
            task_handle, num_samps_per_chan, auto_start, timeout, numpy_array,
            ctypes.byref(samps_per_chan_written), None)
        self.check_for_error(error_code, samps_per_chan_written=samps_per_chan_written.value)

        return samps_per_chan_written.value

    def hash_task_handle(self, task_handle):
        return hash(task_handle.value)

    def check_for_error(self, error_code, samps_per_chan_written=None, samps_per_chan_read=None):
        if not error_code:
            return

        if error_code < 0:
            extended_error_info = self.get_extended_error_info()

            if samps_per_chan_read is not None:
                raise DaqReadError(extended_error_info, error_code, samps_per_chan_read)
            elif samps_per_chan_written is not None:
                raise DaqWriteError(extended_error_info, error_code, samps_per_chan_written)
            else:
                raise DaqError(extended_error_info, error_code)

        elif error_code > 0:
            error_string = self.get_error_string(error_code)

            warnings.warn(DaqWarning(error_string, error_code))


def is_string_buffer_too_small(error_code):
    return (
        error_code == DAQmxErrors.BUFFER_TOO_SMALL_FOR_STRING or
        error_code == DAQmxWarnings.CAPI_STRING_TRUNCATED_TO_FIT_BUFFER)


def is_array_buffer_too_small(error_code):
    return error_code == DAQmxErrors.WRITE_BUFFER_TOO_SMALL